【问题标题】:Convert string to its lower case ascii hexadecimal representation将字符串转换为其小写 ascii 十六进制表示
【发布时间】:2021-08-04 22:40:05
【问题描述】:

我正在为支付集成创建一个 sha-256 哈希 要求是(来自银行的指示):

第 1 步:创建字符串 例如 987654321012013:07:16-09:57:081.00826TopSecret

第 2 步:将创建的字符串转换为其 ascii 十六进制表示 例如 3938373635343332313031323031333a30373a31362d30393a35373a3038312e3030383236546f70536563726574

第 3 步:生成转换后字符串的 sha-256 哈希 例如 3d7e75aa0b4e0e1d4a7ac87e451e64692cced46f4358ef35a69d96721341243c

问题: 我的代码中的第 2 步给出了大写的 A、D、E、F 等,然后生成与给定示例不同的 sha-256。我需要生成具有小写十六进制表示的字节数组。

这是我的代码(在 .NET 4.5.2 中):

string hash = createHash( inputstring );

public static string createHash(string inputString)
{
      SHA256 sha256 = SHA256Managed.Create();
      byte[] bytes = Encoding.ASCII.GetBytes(inputString);
      // need my bytes to be lower case
      byte[] hash = sha256.ComputeHash(bytes);
      return GetStringFromHash(hash).ToLower();
}

感谢您的帮助。

【问题讨论】:

  • .ToLower() 的输入数据有什么问题?
  • 什么?你在什么时候将bytes 转换为字符串`? byte 没有大写或小写;它是计算机内存中的一个数字。
  • 另外,您没有将字符串转换为十六进制表示形式(这将再次成为字符串)。
  • @Llama 因为输入字符串区分大小写,问题是中间步骤需要小写 Caius - 谢谢,我意识到,我的问题在于该数字的表示跨度>

标签: c# character-encoding byte sha256


【解决方案1】:

缺少的步骤是转换为十六进制表示的字符串。我们可以将字符串中的字符转换为int,然后用.ToString("x2")将其格式化为十六进制。

//Step 1: Create the string
string secret = "987654321012013:07:16-09:57:081.00826TopSecret";

//Step 2: Convert the created string to its ascii hexadecimal representation
string hexString = String.Concat(secret.Select(c => ((int)c).ToString("x2")));
// Has already lower case hex digits here. No action required.

//Step 3: generate sha-256 hash of the converted string
byte[] bytes = Encoding.ASCII.GetBytes(hexString);
SHA256 sha256 = SHA256Managed.Create();
byte[] hash = sha256.ComputeHash(bytes);

// Return the hash bytes as hexadecimal string
return GetStringFromHash(hash);

请注意,字符串是字符的枚举。即,String Class 实现了IEnumerable<char>。因此,我们可以使用 LINQ Select 来转换输入字符串的字符。请注意,在 C# 中,char 类型被视为 16 位数字类型。因此,您可以将其与int(32 位)相互转换。


你可以像这样实现GetStringFromHash

private static string GetStringFromHash(byte[] hash)
{
    return String.Concat(hash.Select(b => b.ToString("x2")));
}

请注意,.ToString("x2") 生成小写十六进制数字。因此,不再需要.ToLower()


请注意,使用 ASCII 的要求将字符集限制在(char)1 .. (char)127 范围内。 (char)0 被排除在外,因为它在某些 API 中可能被误解为字符串终止符。因此,不确定此限制是否涉及秘密输入字符串或十六进制字符串或两者。将秘密字符串限制在(char)1 .. (char)255 范围内可能就足够了,这将包括一些变音符号,但肯定会排除例如汉字。

【讨论】:

    【解决方案2】:

    你已经散列了这个:

    987654321012013:07:16-09:57:081.00826TopSecret

    不是它的 ascii 十六进制表示


    我怀疑你想替换

    // need my bytes to be lower case
    

    类似的东西

    var inputToHash = BitConverter.ToString(bytes).Replace("-","").ToLower();
    

    或者类似的东西

    var inputToHash = string.Concat(bytes.Select(b => b.ToString("x2")));
    

    然后散列inputToHash(再次获取字节),而不是bytes


    如果您需要更高的性能,也许使用 stringbuilder 而不是 bitconverter 或 linq

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-11-21
      • 2015-05-22
      • 2011-10-26
      • 2014-11-16
      • 1970-01-01
      • 2019-01-08
      • 2011-06-14
      相关资源
      最近更新 更多