将哈希转换为十六进制字符串

Posted

技术标签:

【中文标题】将哈希转换为十六进制字符串【英文标题】:Convert hash to a hexadecimal character string 【发布时间】:2010-11-29 00:15:21 【问题描述】:

在此页面上:

http://www.shutterfly.com/documentation/OflyCallSignature.sfly

它说,一旦你生成了一个哈希,你就会:

csharp 中是否有代码可以做到这一点?

【问题讨论】:

【参考方案1】:

要获取哈希,请使用System.Security.Cryptography.SHA1Managed class。

编辑:像这样:

byte[] hashBytes = new SHA1Managed().ComputeHash(Encoding.UTF8.GetBytes(str));

要将哈希转换为十六进制字符串,请使用以下代码:

BitConverter.ToString(hashBytes).Replace("-", "");

如果您想要更快的实现,请使用以下函数:

private static char ToHexDigit(int i) 
    if (i < 10) 
        return (char)(i + '0');
    return (char)(i - 10 + 'A');

public static string ToHexString(byte[] bytes) 
    var chars = new char[bytes.Length * 2 + 2];

    chars[0] = '0';
    chars[1] = 'x';

    for (int i = 0; i < bytes.Length; i++) 
        chars[2 * i + 2] = ToHexDigit(bytes[i] / 16);
        chars[2 * i + 3] = ToHexDigit(bytes[i] % 16);
    

    return new string(chars);

【讨论】:

【参考方案2】:

我还不能发表评论,没有足够的代表,但 Lior 将 Java 与 C# 混合在一个非常错误的答案中。

C# 中的字节是无符号字节,这与 C# 中所有其他整数类型完全相反,默认情况下是有符号的。

0xFF 部分完全没有意义,因为即使字节已签名,例如 0xFE 也是 -2。例如,对 0xFE 和 0xFF 使用按位与不会阻止负数 0xFE 成为结果。 0x7F 会。

关于最佳答案,我很确定这些微优化可能会有所帮助,尽管它们是微优化,可能不会产生任何实际影响,因为 JIT 编译器可能只是做其他事情,并且因为计算机是太快了。

    chars[2 * i + 2] = ToHexDigit(bytes[i] / 16);
    chars[2 * i + 3] = ToHexDigit(bytes[i] % 16);

小改动使其使用位移和按位运算,而不是除法器和模数。

    chars[2 * i + 2] = ToHexDigit((bytes[i] >> 4) & 0xF);
    chars[2 * i + 3] = ToHexDigit(bytes[i] & 0xF);

这是另一种“优化”,尽管我认为它更具可读性。也许那是因为我对大部分 ASCII 表都熟记于心。

    private static char ToHexDigit(int i)
    
        return (char)(i + (i < 10 ? 48 : 55));
    

如果您想实现小写十六进制(不带 ToLower),只需将 55 与 87 交换即可。这很简单。

更新:看起来 Lior 或其他人删除了他非常偏离的答案。这是一个很好的举措。

【讨论】:

以上是关于将哈希转换为十六进制字符串的主要内容,如果未能解决你的问题,请参考以下文章

将文件中的字符串转换为十六进制(Ruby)第二部分

哈希算法的用途

在 Java 中,如何将字节数组转换为十六进制数字字符串,同时保持前导零? [复制]

在 Java 中,如何将字节数组转换为十六进制数字字符串,同时保持前导零? [复制]

如何在C中将无符号字符数组转换为十六进制字符串

将从 SHA1 返回的 unsigned char* 转换为字符串