Перевести с Java на C #: простой код для перекодирования строки - PullRequest
1 голос
/ 29 мая 2010

Нам была отправлена ​​эта формула для шифрования строки, написанной на 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 ]

4 голосов
/ 29 мая 2010

В вашей версии C # я бы предложил попробовать UTF8Encoding, UnicodeEncoding или UTF32Encoding вместо вашего текущего ASCIIEncoding.

В Java String.getBytes метод использует кодировку платформы по умолчанию, если вы ее не указали (а вы не указали). Кодировка платформы по умолчанию вряд ли будет ASCII.

2 голосов
/ 29 мая 2010

Как говорит 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));
2 голосов
/ 29 мая 2010

Я бы посоветовал вам разобраться с этим.

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, перейдите к следующему шагу. Сравните хэши SHA1 для тех же байтов в Java и .NET. Это должно соответствовать, но мне нравится быть методичным и никогда не делать предположений, особенно когда их легко и быстро проверить.

3 - После того, как вы показали, что у вас одинаковые байты SHA1, вы можете выполнить кодирование Base 64 и сравнить.

4- Наконец, выполните кодировку Url, если вы зашли так далеко, я подозреваю, что вы найдете разницу в регистре. IIRC .NET Url-кодирование использует нижний регистр, и из вашего примера я вижу, что Java использует верхний регистр, например% 3D в Java, вероятно, будет% 3d в .NET.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...