Конвертировать C # CUSTOM функцию getSHA512 в Ruby - PullRequest
0 голосов
/ 23 июня 2010

Мне было интересно, может ли кто-нибудь помочь мне преобразовать этот метод в 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;
}

Заранее спасибо


UPDATE:

Я просто хотел бы прояснить, что, к сожалению, этот метод предназначен не только для генерации SHA512, но и для пользовательского. Я считаю, что Digest :: SHA512.hexdigest был бы просто экземпляром SHHast, но если вы внимательно посмотрите на метод, вы увидите, что он немного отличается от простого генерирования хеша. Следует за результатом обеих функций.

# in C#
getSHA512("hello") => "5165d592a6afe59f80d07436e35bd513b3055429916400a16c1adfa499c5a8ce03a370acdd4dc787d04350473bea71ea8345748578fc63ac91f8f95b6c140b93"

# in Ruby
Digest::SHA512.hexdigest("hello") || Digest::SHA2 => "9b71d224bd62f3785d96d46ad3ea3d73319bfbc2890caadae2dff72519673ca72323c3d99ba5c11d7c7acc6e14b8c5da0c4663475c2e5c3adef46f73bcdec043" 

Ответы [ 2 ]

3 голосов
/ 23 июня 2010
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.


Вне темы: 9 строк кода сокращены до 1.Я люблю Руби!

Ну, на самом деле это немного несправедливо.Вы могли бы написать что-то вроде этого:

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) и, самое главное, избавляется от этого уродливого явного цикла for в стиле 1950-х дляхороший фолд в стиле 1960-х (aka. reduce aka. inject aka. Aggregate aka. inject:into: ... это все то же самое).

Возможно, есть еще более элегантный способ написать это,но а) я на самом деле не знаю C # и .NET и б) этот вопрос о Ruby.Фокус, Йорг, фокус!: -)

Aaand ... нашел его:

return string.Join("", from b in hashValue select string.Format("{0:x2}", b));

Я знал, должен быть где-то эквивалент Enumerable#join Руби где-то, я просто искал внеправильное место.

0 голосов
/ 23 июня 2010

Используйте класс Digest :: SHA2 .

...