У меня есть строка в PHP, которая преобразуется в массив байтов и хэшируется.
Строка, преобразованная в массив байтов, выглядит так:
"г". chr (0). «Пу»;
Мне нужен эквивалентный массив байтов в C #, поэтому я могу получить тот же хеш.
EDIT: вот ПОЛНАЯ проблема, в результате хеш не то же самое.
PHP
$api_secret = '5432919427bd18884fc2a6e48b65dfba48fd9a1a46e3468b52fadbc6d6b463425'; $data = 'payment_currency=USD&group_orders=0&count=100&nonce=1385689989977529'; $endpoint = '/info/orderbook'; $signature = hash_hmac('sha512', $endpoint . chr(0) . $data, $api_secret); $result = base64_encode($signature);
C #
var apiSecret = "5432919427bd18884fc2a6e48b65dfba48fd9a1a46e3468b52fadbc6d6b463425"; var data = "payment_currency=USD&group_orders=0&count=100&nonce=1385689989977529"; var endPoint = "/info/orderbook"; System.Text.UTF8Encoding encoding = new System.Text.UTF8Encoding(); String message = endpPoint + Convert.ToChar(0) + data; var hmacsha512 = new HMACSHA512(encoding.GetBytes(message)); var result = Convert.ToBase64String(hmacsha512.Hash);
Я пробовал различную кодировку base64, например:
public static string ByteToString(byte[] buff) { string sbinary = ""; for (int i = 0; i < buff.Length; i++) sbinary += buff[i].ToString("X2"); /* hex format */ return sbinary; }
но в конечном итоге проблема заключается в том, что байтовый массив, который хэшируется из-за использования chr (0) php.
Я отвечаю на него снова, потому что вы изменили весь вопрос, так что есть новое решение для вашего нового вопроса.
Во-первых, HMACSHA512 не даст того же результата, что и ваш php-код. Кстати, ваш хэш-код, созданный PHP:
41028bb90af31dc6e7fa100a8ceb1e220bfedf67ea723292db9a4e1c14f69c73adf30eeba61ab054cdc91c82f6be2f76dd602392be630b5e99b1f86da1460cbe
Чтобы сделать тот же результат в C #, я создал класс BillieJeansSHA512
чтобы сделать хэш равным PHP. Кроме того, вместо использования encoding.GetBytes
для преобразования байта [] в String я создал метод ByteToString
для правильной конвертации.
Ow, следующий код не прост как PHP, но я призываю вас или кого-то сделать это проще с тем же хэшем PHP! Я смею тебя, я ДВОЙНО СДЕЛАЮ ВАС! Перейдем к коду:
//These are not default imports, so you need to use it using System.Text; using System.Security.Cryptography; //Before your actual class, you need to make your custom 512 public class BillieJeansSHA512 : HMAC { public BillieJeansSHA512(byte[] key) { HashName = "System.Security.Cryptography.SHA512CryptoServiceProvider"; HashSizeValue = 512; BlockSizeValue = 128; Key = (byte[])key.Clone(); } } //Now, there's your actual class public class HelloWorld{ //First, use this method to convert byte to String like a boss static string ByteToString(byte[] buff) { string sbinary = ""; for (int i = 0; i < buff.Length; i++) sbinary += buff[i].ToString("x2"); /* hex format */ return sbinary; } //Now let's get it started! public static void Main(String []args){ System.Text.UTF8Encoding encoding = new System.Text.UTF8Encoding(); //Your data var apiSecret = "5432919427bd18884fc2a6e48b65dfba48fd9a1a46e3468b52fadbc6d6b463425"; var data = "payment_currency=USD&group_orders=0&count=100&nonce=1385689989977529"; var endPoint = "/info/orderbook"; String message = endPoint + Convert.ToChar(0) + data; //Hash will be stored here String hash = ""; //put your key at your custom 512 BillieJeansSHA512 hmacsha512 = new BillieJeansSHA512(encoding.GetBytes(apiSecret)); //hash'em all byte[] result = hmacsha512.ComputeHash(encoding.GetBytes(message)); //convert bytes to string hash = ByteToString(result); //See it :) Console.WriteLine(hash); //Or if you using it at a web-page, this is it. //Response.Write(hash) //Now the easy part, convert it to base64 var bytesTo64 = System.Text.Encoding.UTF8.GetBytes(hash); String hash64 = System.Convert.ToBase64String(bytesTo64); } }
… ну, вот и все. String hash
имеет тот же хэш, что и PHP:
41028bb90af31dc6e7fa100a8ceb1e220bfedf67ea723292db9a4e1c14f69c73adf30eeba61ab054cdc91c82f6be2f76dd602392be630b5e99b1f86da1460cbe
и String hash64
имеет такое же закодированное значение base64, что и PHP:
NDEwMjhiYjkwYWYzMWRjNmU3ZmExMDBhOGNlYjFlMjIwYmZlZGY2N2VhNzIzMjkyZGI5YTRlMWMxNGY2OWM3M2FkZjMwZWViYTYxYWIwNTRjZGM5MWM4MmY2YmUyZjc2ZGQ2MDIzOTJiZTYzMGI1ZTk5YjFmODZkYTE0NjBjYmU=
Он также задал его как массив byte
, это самое важное, потому что нужно использовать преобразование символов в байты:
//Conversion object System.Text.UTF8Encoding encoding = new System.Text.UTF8Encoding(); //Your any String text String stringText = "g" + Convert.ToChar(0) + "poo"; //Convert to the wanted byte array byte[] byteArray = encoding.GetBytes(stringText);
Вы также можете сделать то же самое в одной строке, если хотите 🙂
byte[] byteArray = new System.Text.UTF8Encoding().GetBytes("g" + Convert.ToChar(0) + "poo");
Вы можете использовать метод Convert.ToChar(Int32)
для представления значений unicode в качестве символов.
Использование: "g" + Convert.ToChar(0) + "poo"