从 Java 转换为 C#:重新编码字符串的简单代码

发布于 2024-09-03 12:42:19 字数 835 浏览 6 评论 0原文

我们收到这个公式来加密用 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))));

但是输出却相差甚远。它甚至没有百分号。有没有可能有人知道我们哪里出了问题?

We were sent this formula to encrypt a string written in 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"

Our attempt at writing this in C# is:

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

However the output is no where near the same. It doesn't even have percent signs in it. Any chance anyone would know where we are going wrong?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

分开我的手 2024-09-10 12:42:19

在您的 C# 版本中,我建议尝试 UTF8Encoding< /code>, UnicodeEncodingUTF32Encoding 而不是您当前的 ASCIIEncoding< /代码>

Java 的 如果您没有指定(而且您也没有指定),String.getBytes 方法将使用平台的默认编码。该平台的默认编码不太可能是 ASCII。

In your C# version, I would suggest trying UTF8Encoding, UnicodeEncoding or UTF32Encoding rather than your current ASCIIEncoding.

Java's String.getBytes method uses the platform's default encoding if you don't specify one (and you don't). The platform's default encoding is unlikely to be ASCII.

抽个烟儿 2024-09-10 12:42:19

就像 LukeH 所说,如果您在同一台计算机上同时运行 Java 版本和 C# 版本,您可以尝试将 C# 版本中的编码更改为 Encoding.Default.GetBytes(myInput) 。

如果失败或者不是一个选项,您可以随时尝试打印字节值并将其与 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));

Like LukeH says you can try changing the encoding in the C# version to Encoding.Default.GetBytes(myInput) if you run both the Java version and the C# version on the same machine.

If that fails or isn't an option you can always try printing the byte values and compare it to the respective step in Java just to find out where the error lies:

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));
旧竹 2024-09-10 12:42:19

我建议你把这个分解掉。

1-比较从 Java String.getBytes() 和 .NET Encoding.GetBytes() 返回的结果
下面是一些 .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 中相同字节的 SHA1 哈希值。这应该匹配,但我喜欢有条不紊,从不很少做出假设,尤其是当它们可以快速且容易验证时。

3- 一旦您显示出具有相同的 SHA1 字节,您就可以进行 Base 64 编码并进行比较。

4-最后执行 Url 编码,如果你到目前为止我怀疑你会发现大小写的差异。 IIRC .NET Url 编码使用小写,从您的示例中我看到 Java 使用大写,例如 Java 中的 %3D 在 .NET 中可能是 %3d。

I would suggest you break this down.

1- Compare what you get back from the Java String.getBytes() and .NET Encoding.GetBytes()
Here is some .NET code that will dump the bytes for your string for every encoding, compare the results with those from 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- If you find the right encoding from step 1, move to the next step. Compare the SHA1 hashes for the same bytes in Java and .NET. This should match, but I like to be methodical and never seldom make assumptions especially when they are quick and easy to verify.

3- Once you have shown you have the same SHA1 bytes, you can do the Base 64 encoding and compare.

4- Finally perform the Url encoding, if you got this far I suspect you will find a difference in casing. IIRC .NET Url encode uses lower case, and from your sample I see Java is using upper case, for example %3D in Java will probably be %3d in .NET.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文