c# and Encoding.ASCII.GetString

后端 未结 5 1896
南旧
南旧 2020-12-06 03:51
byte[] header = new byte[]{255, 216}; 

string ascii =  Encoding.ASCII.GetString(header);

I expect ASCII to be equal to be FFD8 (JPEG SOI marker)<

5条回答
  •  抹茶落季
    2020-12-06 04:30

    Yes, that's because ASCII is only 7-bit - it doesn't define any values above 127. Encodings typically decode unknown binary values to '?' (although this can be changed using DecoderFallback).

    If you're about to mention "extended ASCII" I suspect you actually want Encoding.Default which is "the default code page for the operating system"... code page 1252 on most Western systems, I believe.

    What characters were you expecting?

    EDIT: As per the accepted answer (I suspect the question was edited after I added my answer; I don't recall seeing anything about JPEG originally) you shouldn't convert binary data to text unless it's genuinely encoded text data. JPEG data is binary data - so you should be checking the actual bytes against the expected bytes.

    Any time you convert arbitrary binary data (such as images, music or video) into text using a "plain" text encoding (such as ASCII, UTF-8 etc) you risk data loss. If you have to convert it to text, use Base64 which is nice and safe. If you just want to compare it with expected binary data, however, it's best not to convert it to text at all.

    EDIT: Okay, here's a class to help image detection method for a given byte array. I haven't made it HTTP-specific; I'm not entirely sure whether you should really fetch the InputStream, read just a bit of it, and then fetch the stream again. I've ducked the issue by sticking to byte arrays :)

    using System;
    using System.Collections.Generic;
    using System.Collections.ObjectModel;
    using System.Linq;
    
    public sealed class SignatureDetector
    {
        public static readonly SignatureDetector Png =
            new SignatureDetector(0x89, 0x50, 0x4e, 0x47);
    
        public static readonly SignatureDetector Bmp =
            new SignatureDetector(0x42, 0x4d);
    
        public static readonly SignatureDetector Gif =
            new SignatureDetector(0x47, 0x49, 0x46);
    
        public static readonly SignatureDetector Jpeg =
            new SignatureDetector(0xff, 0xd8);
    
        public static readonly IEnumerable Images =
            new ReadOnlyCollection(new[]{Png, Bmp, Gif, Jpeg});
    
        private readonly byte[] bytes;
    
        public SignatureDetector(params byte[] bytes)
        {
            if (bytes == null)
            {
                throw new ArgumentNullException("bytes");
            }
            this.bytes = (byte[]) bytes.Clone();
        }
    
        public bool Matches(byte[] data)
        {
            if (data == null)
            {
                throw new ArgumentNullException("data");
            }
            if (data.Length < bytes.Length)
            {
                return false;
            }
            for (int i=0; i < bytes.Length; i++)
            {
                if (data[i] != bytes[i])
                {
                    return false;
                }
            }
            return true;
        }    
    
        // Convenience method
        public static bool IsImage(byte[] data)
        {
            return Images.Any(detector => detector.Matches(data));
        }        
    }
    

提交回复
热议问题