2010-05-28 2 views
1

Мы были посланы эту формулу, чтобы зашифровать строку, написанный на Java:Перевести с Java на C#: простой код перекодировать строку

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)))); 

Однако выход не там, где рядом. В нем нет даже признаков процента. Любая вероятность, что кто-нибудь узнает, где мы ошибаемся?

ответ

4

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

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

2

Я предлагаю вам сломать это.

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 encode использует строчный регистр, и из вашего примера я вижу, что Java использует верхний регистр, например,% 3D в Java, вероятно, будет% 3d в .NET.

2

Как 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)); 
Смежные вопросы