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
Руби где-то, я просто искал внеправильное место.