【问题标题】:c# and Encoding.ASCII.GetStringc# 和 Encoding.ASCII.GetString
【发布时间】:2009-05-31 14:45:23
【问题描述】:
byte[] header = new byte[]{255, 216}; 

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

我希望 ASCII 等于 FFD8(JPEG SOI 标记)

相反,我得到“??????”

【问题讨论】:

  • 你在哪里看到“????” ?...请注意,0xFFD8 不可打印。
  • 编辑问题,添加下面提供的新信息。我想你可能问错了问题?也许最好在你提出真正问题的地方提出一个全新的问题......“编写一个函数来确定文件是否是仅基于标题信息的图像”

标签: c# encoding ascii


【解决方案1】:

在这种情况下,您最好比较字节数组而不是转换为字符串。

如果您必须转换为字符串,我建议使用编码 Latin-1 aka ISO-8859-1 aka Code Page 28591 编码,因为此编码会将所有十六进制值在 0-255 范围内的字节映射到 Unicode具有相同十六进制值的字符 - 在这种情况下很方便。以下任何一项都会得到这种编码:

Encoding.GetEncoding(28591)
Encoding.GetEncoding("Latin1")
Encoding.GetEncoding("ISO-8859-1")

【讨论】:

  • 为建议干杯。为什么要比较字节数组?
  • 因为它是二进制数据。 JPEG 不是文本,因此不应转换为文本。
【解决方案2】:

是的,那是因为 ASCII 只有 7 位 - 它没有定义任何高于 127 的值。编码通常将未知的二进制值解码为“?” (虽然这可以使用DecoderFallback 更改)。

如果您要提及“扩展 ASCII”,我怀疑您实际上想要 Encoding.Default,它是“操作系统的默认代码页”...code page 1252 在大多数西方系统上,我相信。

你期待什么角色?

编辑:根据接受的答案(我怀疑在我添加答案后对问题进行了编辑;我不记得最初看到任何关于 JPEG 的内容)您不应该将二进制数据转换为文本,除非它是真正编码的文本数据。 JPEG 数据是 二进制 数据 - 因此您应该检查实际字节与预期字节。

只要您使用“纯”文本编码(例如 ASCII、UTF-8 等)将任意二进制数据(例如图像、音乐或视频)转换为文本,您就有数据丢失的风险。如果您 将其转换为文本,请使用既美观又安全的 Base64。但是,如果您只想将其与预期的二进制数据进行比较,最好不要将其转换为文本。

编辑:好的,这是一个帮助给定字节数组的图像检测方法的类。我还没有让它特定于 HTTP。我不完全确定您是否真的应该获取InputStream,只读一点,然后再次获取流。我通过坚持字节数组来回避这个问题:)

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<SignatureDetector> Images =
        new ReadOnlyCollection<SignatureDetector>(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));
    }        
}

【讨论】:

  • 大声笑,又不是这个...由于您的编辑而删除了反对票。鉴于作者现在添加的新信息 - 最好为他正确编写 IsFileImage 方法。你在做那个?如果你是...,我不会浪费我的时间......
  • 注意,我没看到是谁这样回答的。如果我知道是你,我会评论并解释他想要做什么......也许仍然是一个不赞成票:P 我最初认为这是一个糟糕的答案 - 但话又说回来,这也是一个糟糕的问题。 :)
  • 我目前没有实现 IsFileImage,但以后可能会实现。在讨论 JPEG 部分的编辑之前,作者只是问为什么它显示的是问号而不是预期的字符 (IIRC)。再一次,我认为反对票几乎总是值得评论。为什么其他人从评论中获得的收益比我少?
  • 我投了很多票 - 我看到不好的答案,我希望它们低于更好的答案。它就是它的工作原理。要求评论会很烦人。有些答案不值得评论。你可以把它带到用户语音,但它总是被拒绝。就个人而言,我会试着看看我是否对 Jon Skeet 投了反对票并写了一个小便条。但大多数时候它是不需要的 - 很清楚(甚至对你来说)你的答案有什么问题。
  • 另请注意 Jon,没有添加 JPEG 注释的编辑。它一直都在。你只是错过了它。我以前也犯过一次错误——很痛苦。大声笑
【解决方案3】:

如果你接着写:

Console.WriteLine(ascii)

并期望“FFD8”打印出来,这不是 GetString 的工作方式。为此,您需要:

 string ascii = String.Format("{0:X02}{1:X02}", header[0], header[1]);   

【讨论】:

  • 然后它会打印“3F3F” - 最大的问题(IMO)是它被转换成文本的事实。
【解决方案4】:

我曾经写过一个自定义编码器/解码器,它将字节 0-255 编码为 un​​icode 字符 0-255 并再次返回。

它只对在实际上不是字符串的东西上使用字符串函数非常有用。

【讨论】:

    【解决方案5】:

    你确定“???”结果呢?

    结果是什么:

    (int)ascii[0]
    (int)ascii[1]
    

    另一方面,纯 ASCII 只是 0-127...

    【讨论】:

      猜你喜欢
      • 2021-07-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-12-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多