2017-02-17 7 views
4

Я новичок в Crystal. Я хотел бы попытаться найти хэш-строку шестнадцатеричной строки SHA256. Я сумел получить что-то работу:Crystal: Как я могу найти хэш SHA256 двоичного значения?

sha256 = OpenSSL::Digest.new("sha256") 
puts sha256.update("abcd") 

Но я не знаю, как поставить двоичное значение «ABCD» в хэш-функции, или получить двоичный выход. Я в основном хотел бы быть в состоянии воссоздать эту функцию Ruby:

def hash256(hex) 
    # 1. Convert hex string to array, and pack in to binary 
    binary = [hex].pack("H*") 

    # 2. Hash the binary value (returns binary) 
    hash1 = Digest::SHA256.digest(binary) 

    # 3. Hash it again (returns binary) 
    hash2 = Digest::SHA256.digest(hash1) 

    # 4. Convert back to hex (must unpack as array) 
    result = hash2.unpack("H*")[0] 

    return result 
end 

Можно ли использовать SHA256 с двоичными значениями в кристалле?

ответ

8

Декодирование строку шестнадцатеричных символов в двоичный срез не в настоящее время часть кристалла стандартной библиотеки, так что я написал функцию декодирования себя:

def hex_decode(hex) 
    return unless hex.size % 2 == 0 

    slice = Slice(UInt8).new(hex.size/2) 
    0.step(to: hex.size - 1, by: 2) do |i| 
    high_nibble = hex.to_unsafe[i].unsafe_chr.to_u8?(16) 
    low_nibble = hex.to_unsafe[i + 1].unsafe_chr.to_u8?(16) 
    return unless high_nibble && low_nibble 

    slice[i/2] = (high_nibble << 4) | low_nibble 
    end 

    slice 
end 

Эта функция принимает String, содержащий шестнадцатеричные символы, то декодирует его в Slice(UInt8) (или возвращает nil, если шестнадцатеричный код недействителен).

Тогда полный код эквивалентен коду рубинового вставили выше будет:

def hash256(hex_string) 
    data = hex_decode(hex_string) 
    raise "Invalid hexadecimal" unless data 

    hash = OpenSSL::Digest.new("SHA256") 
    hash.update(data) 
    hash1 = hash.digest 

    hash = OpenSSL::Digest.new("SHA256") 
    hash.update(hash1) 

    hash.hexdigest 
end 

Хотя у меня есть вопрос, почему вы хотели бы использовать SHA256 дважды. Я бы рекомендовал изменения хэш-функции, как так:

def hash256(hex_string) 
    data = hex_decode(hex_string) 
    raise "Invalid hexadecimal" unless data 

    hash = OpenSSL::Digest.new("SHA256") 
    hash.update(data) 

    hash.hexdigest 
end 
+0

Большое вам спасибо. Причиной использования SHA256 два раза является то, что я пытаюсь изучить Crystal, написав библиотеку биткойнов, и по какой-то причине вещи обычно становятся хешированными дважды. – inersha

0

Для сценария Ruby, генерирующего SHA256 хэш с digest самоцвета:

require "digest" 

def calc_hash 
    sha = Digest::SHA256.new 
    sha.update(@index.to_s + @timestamp.to_s + @data + @previous_hash) 
    sha.hexdigest 
end 

Для Кристалл, вы можете потребовать openssl и использовать вместо:

require "openssl" 

def calc_hash 
    hash = OpenSSL::Digest.new("SHA256") 
    hash.update(@index.to_s + @timestamp.to_s + @data + @previous_hash) 
    hash.hexdigest 
end 

 Смежные вопросы

  • Нет связанных вопросов^_^