代码之家  ›  专栏  ›  技术社区  ›  Zachary Scott

从Java到C语言的转换:简单代码重新编码一个字符串

  •  1
  • Zachary Scott  · 技术社区  · 15 年前

    我们发送了这个公式来加密用Java编写的字符串:

    String        myInput = "test1234";
    MessageDigest      md = MessageDigest.getInstance("SHA");
    byte[]            myD = md.digest(myInput.getBytes());
    BASE64Encoder    en64 = new BASE64Encoder();
    String       myOutput = new String ( 
                                Java.net.URLEncoder.encode( en64.encode(myD)));
    // myOutput becomes "F009U%2Bx99bVTGwS3cQdHf%2BJcpCo%3D"
    

    我们试图用C来写这篇文章是:

    System.Security.Cryptography.SHA1 sha1 = 
        new System.Security.Cryptography.SHA1CryptoServiceProvider();
    string myOutput = HttpUtility.UrlEncode( 
                          Convert.ToBase64String( 
                              sha1.ComputeHash( 
                                  ASCIIEncoding.Default.GetBytes(myInput))));
    

    然而,输出在哪里几乎相同。它甚至没有百分号。有没有可能有人知道我们哪里出错了?

    3 回复  |  直到 15 年前
        1
  •  4
  •   LukeH    15 年前

    在你的C版中,我建议你尝试一下 UTF8Encoding , UnicodeEncoding UTF32Encoding 而不是你现在 ASCIIEncoding .

    爪哇 String.getBytes 方法使用平台的默认编码(如果不指定)。平台的默认编码不太可能是ASCII。

        2
  •  2
  •   Don    15 年前

    就像Lukeh说的,你可以尝试将C版本中的编码改为 Encoding.Default.GetBytes(myInput) 如果在同一台机器上运行Java版本和C版本。

    如果失败或不是一个选项,你可以尝试打印字节值,并将其与Java中的相应步骤进行比较,以找出错误所在:

    String myInput = "test1234";
    System.Security.Cryptography.SHA1 crypto = new System.Security.Cryptography.SHA1CryptoServiceProvider();
    Byte[] myInputBytes = Encoding.Default.GetBytes(myInput);
    Console.WriteLine(BitConverter.ToString(myInputBytes));
    Byte[] hash = crypto.ComputeHash(myInputBytes);
    Console.WriteLine(BitConverter.ToString(hash));
    
        3
  •  2
  •   Chris Taylor    15 年前

    我建议你把这个分解。

    1比较从Java字符串返回的内容。 下面是一些.NET代码,这些代码将为每个编码释放字符串的字节,并将结果与Java进行比较。

    string myInput = "test1234";
    foreach (EncodingInfo ei in Encoding.GetEncodings())
    {
      byte[] bytes = ei.GetEncoding().GetBytes(myInput);
      Console.WriteLine("{0}\t\t{1}", 
        BitConverter.ToString(bytes), ei.DisplayName);
    }
    

    2-如果从步骤1中找到正确的编码,请转到下一步。比较Java和.NET中相同字节的SH1哈希值。这应该是相匹配的,但我喜欢有条理的,从不做假设,尤其是当假设快速且易于验证时。

    3-一旦显示了相同的sha1字节,就可以进行base 64编码和比较。

    4-最后执行URL编码,如果到目前为止,我怀疑您会发现大小写的不同。IURC.NET URL编码使用小写,从您的示例中,我看到Java使用大写字母,例如,在Java中的%3D可能是.%3D在.NET中。