Конвертировать C # пользовательскую функцию GetSha512 в Ruby

StackOverflow https://stackoverflow.com/questions/3101864

  •  29-09-2019
  •  | 
  •  

Вопрос

Мне было интересно, может ли кто -нибудь помочь мне получить этот метод в Руби, это вообще возможно?

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 класс.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top