Crystal: 如何找到二进制值的 SHA256 哈希值?
Crystal: How can I find the SHA256 hash of a binary value?
我是 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
是否可以在 Crystal 中对二进制值使用 SHA256?
将一串十六进制字符解码为二进制切片目前不是crystal标准库的一部分,所以我自己写了一个解码函数:
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)
(如果十六进制无效,则为 returns nil
)。
那么与上面粘贴的 ruby 代码等效的完整代码将是:
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
对于 Ruby 脚本生成 SHA256 散列 digest
gem:
require "digest"
def calc_hash
sha = Digest::SHA256.new
sha.update(@index.to_s + @timestamp.to_s + @data + @previous_hash)
sha.hexdigest
end
对于 Crystal,您可以要求 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
您可以只使用十六进制字符串的 .hexbytes
:
# Sha256 hash of hex string
hex = "abcd"
p OpenSSL::Digest.new("sha256").update(hex).final.hexstring
# => "88d4266fd4e6338d13b845fcf289579d209c897823b9217da3e161936f031589"
# Sha256 hash of hex data but on binary value
bin = hex.hexbytes
p OpenSSL::Digest.new("sha256").update(bin).final.hexstring
# => "123d4c7ef2d1600a1b3a0f6addc60a10f05a3495c9409f2ecbf4cc095d000a6b"
这样,您就可以在 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
是否可以在 Crystal 中对二进制值使用 SHA256?
将一串十六进制字符解码为二进制切片目前不是crystal标准库的一部分,所以我自己写了一个解码函数:
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)
(如果十六进制无效,则为 returns nil
)。
那么与上面粘贴的 ruby 代码等效的完整代码将是:
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
对于 Ruby 脚本生成 SHA256 散列 digest
gem:
require "digest"
def calc_hash
sha = Digest::SHA256.new
sha.update(@index.to_s + @timestamp.to_s + @data + @previous_hash)
sha.hexdigest
end
对于 Crystal,您可以要求 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
您可以只使用十六进制字符串的 .hexbytes
:
# Sha256 hash of hex string
hex = "abcd"
p OpenSSL::Digest.new("sha256").update(hex).final.hexstring
# => "88d4266fd4e6338d13b845fcf289579d209c897823b9217da3e161936f031589"
# Sha256 hash of hex data but on binary value
bin = hex.hexbytes
p OpenSSL::Digest.new("sha256").update(bin).final.hexstring
# => "123d4c7ef2d1600a1b3a0f6addc60a10f05a3495c9409f2ecbf4cc095d000a6b"
这样,您就可以在 Crystal.
中对二进制值使用 SHA256