2017-02-17 6 views
4

저는 Crystal을 처음 사용합니다. 시도해보고 싶습니다 SHA256 16 진수 문자열의 해시. 나는 뭔가 작업을 진행하게 관리했습니다 :크리스탈 : 이진 값의 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 

Crystal에서 이진 값을 사용하여 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 

이 기능은 다음 16 진수 문자를 포함하는 String 소요 Slice(UInt8)으로 디코드합니다 (또는 16 진수가 유효하지 않은 경우 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를 사용하려는 이유에 의문을 가지고 있지만. digest 보석으로 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을 두 번 사용하는 이유는 Bitcoin 라이브러리를 작성하여 Crystal을 배우려고하기 때문에 실제 이유가 없으므로 해시가 두 번 발생하는 경향이 있기 때문입니다. – inersha

0

: 내가 지금 같은 해시 함수를 변경하는 것이 좋습니다 크리스탈 들어

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