0

我正在对数据进行一些异或运算,我的基于十六进制的异或运算进展顺利。建议我使用字节 XOR (^) 并且只使用字节。我认为这不会花时间改变,但我有一些我没想到的奇怪行为。


如果我将字符串作为字节处理,为什么我会得到不同的结果。我期待它是一样的。

 m_hex_string ="124f33e6a118566377f237075354541f0a5a1b"
 m_XOR_string ="662756c6c27732065796586974207468652870"
 m_expected ="the code don't work"
 m_expected_hex ="74686520636f646520646f6e277420776f726b"

def XOR_hex_strings(a,b)
  (a.hex ^ b.hex).to_s(16)
end

def XOR_byte_strings(s1,s2) 
   xored = s1.bytes.zip(s2.bytes).map { |(a,b)| a ^ b }.pack('c*')
end

def hex_digest(hexdigest)
   [hexdigest].pack("H*")
end

   puts "My strings for stack overflow"
   puts "'"+hex_digest(XOR_hex_strings(m_hex_string,m_XOR_string))+"'"
   puts "'"+hex_digest(XOR_byte_strings(m_hex_string,m_XOR_string))+"'"

结果:

 My strings for stack overflow
 'the code don't work'
 'tje`#ode ?on't ~mrk'

对于这两种方法,文本应该是相同的“代码不起作用”。我真的很想知道为什么而不仅仅是一个正确的代码片段。谢谢。

4

1 回答 1

0

正如评论中已经说过的,bytes不考虑十六进制格式,它只返回整数值,,,等"1""2"您可以使用以下方式转换十六进制字符串:"4""f"pack

[m_hex_string].pack("H*")
# => "\x12O3\xE6\xA1\x18Vcw\xF27\aSTT\x1F\nZ\e"

unpack将其转换为字节数组,就像bytes但更明确和更快(IIRC):

[m_hex_string].pack("H*").unpack("C*")
# => [18, 79, 51, 230, 161, 24, 86, 99, 119, 242, 55, 7, 83, 84, 84, 31, 10, 90, 27]

最终方法如下所示:

def XOR_pack_unpack_strings(s1, s2)
  s1_bytes = [s1].pack("H*").unpack("C*")
  s2_bytes = [s2].pack("H*").unpack("C*")
  s1_bytes.zip(s2_bytes).map { |a, b| a ^ b }.pack('C*')
end

如果速度是个问题,请查看fast_xor gem:

require 'xor'

def XOR_fast_xor_strings(s1_hex, s2_hex)
  s1 = [s1_hex].pack("H*")
  s2 = [s2_hex].pack("H*")
  s1.xor!(s2)
end
于 2013-05-08T08:46:18.783 回答