Конвертировать C # пользовательскую функцию GetSha512 в Ruby
Вопрос
Мне было интересно, может ли кто -нибудь помочь мне получить этот метод в Руби, это вообще возможно?
public static string getSHA512(string str){
UnicodeEncoding UE = new UnicodeEncoding();
byte[] HashValue = null;
byte[] MessageBytes = UE.GetBytes(str);
System.Security.Cryptography.SHA512Managed SHhash = new System.Security.Cryptography.SHA512Managed();
string strHex = "";
HashValue = SHhash.ComputeHash(MessageBytes);
foreach (byte b in HashValue){
strHex += string.Format("{0:x2}", b);
}
return strHex;
}
заранее спасибо
ОБНОВИТЬ:
Я просто хотел бы прояснить, что, к сожалению, его метод не только для поколения SHA512, но и пользовательский. Я считаю, что Digest :: SHA512.HexDigest был бы просто экземпляр Shhast, но если вы тщательно ищете метод, вы можете увидеть, что он немного отличается от простого генерации хешта. Следует результату обеих функций.
# in C#
getSHA512("hello") => "5165d592a6afe59f80d07436e35bd513b3055429916400a16c1adfa499c5a8ce03a370acdd4dc787d04350473bea71ea8345748578fc63ac91f8f95b6c140b93"
# in Ruby
Digest::SHA512.hexdigest("hello") || Digest::SHA2 => "9b71d224bd62f3785d96d46ad3ea3d73319bfbc2890caadae2dff72519673ca72323c3d99ba5c11d7c7acc6e14b8c5da0c4663475c2e5c3adef46f73bcdec043"
Решение
require 'digest/sha2'
class String
def sha512
Digest::SHA2.new(512).hexdigest(encode('UTF-16LE'))
end
end
'hello'.sha512 # => '5165d592a6afe59f80d07436e35bd…5748578fc63ac91f8f95b6c140b93'
Как и во всех моих фрагментах кода на Stackoverflow, я всегда предполагаю последнюю версию Ruby. Вот один, который также работает с Ruby 1.8:
require 'iconv'
require 'digest/sha2'
class String
def sha512(src_enc='UTF-8')
Digest::SHA2.new(512).hexdigest(Iconv.conv(src_enc, 'UTF-16LE', self))
end
end
'hello'.sha512 # => '5165d592a6afe59f80d07436e35bd…5748578fc63ac91f8f95b6c140b93'
Обратите внимание, что в этом случае вы должны знать И скажите Ruby о кодировании строка в прямом плане. В Ruby 1.9 Ruby всегда знает, в какой кодировании строки находится, и будет соответственно преобразовать его, при необходимости. Я выбрал UTF-8 в качестве кодировки по умолчанию, потому что он обратно совместим с ASCII, является стандартным кодированием в Интернете, а также иначе широко используется. Однако, например, как .NET и Java UTF-16LE, а не UTF-8. Если ваша строка не UTF-8 или ASCII-кодировка, вам придется пройти в имя кодирования в sha512
метод
Off-Topic: 9 линий кода сокращены до 1. Я люблю Ruby!
Ну, на самом деле это немного несправедливо. Вы могли бы написать это примерно так:
var messageBytes = new UnicodeEncoding().GetBytes(str);
var hashValue = new System.Security.Cryptography.SHA512Managed().
ComputeHash(messageBytes);
return hashValue.Aggregate<byte, string>("",
(s, b) => s += string.Format("{0:x2}", b)
);
Что на самом деле составляет всего 3 линии (разбитые на 5 для макета Stackoverflow), и самое главное избавляется от этого уродливого в стиле 1950-х годов. for
Цикл для приятного сгиба в стиле 1960-х годов (ака. reduce
ака. inject
ака. Aggregate
ака. inject:into:
… все то же самое).
Вероятно, есть еще более элегантный способ написать это, но а) я на самом деле не знаю C# и .net и b) Этот вопрос о Ruby. Фокус, Йорг, Фокус! :-)
Аа и нашел это:
return string.Join("", from b in hashValue select string.Format("{0:x2}", b));
я знал Там было эквивалентно Ruby's Enumerable#join
Где -то я просто смотрел не в том месте.
Другие советы
Использовать Digest :: SHA2 класс.