Ruby Byte XOR странен резултат - моля за помощ

Правех малко XOR на данни и нещата вървяха добре с моя шестнадесетичен XOR. Препоръчва се да използвам байт 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'

Текстът трябва да е един и същ „кодът не работи“ и за двата метода. Наистина бих искал да знам защо, а не просто правилен кодов фрагмент. Благодаря.


person Darren Rogan    schedule 08.05.2013    source източник
comment
Нека позная: който и да е предложил .bytes, не е знаел, че вашите низове са шестнадесетични низове   -  person John Dvorak    schedule 08.05.2013
comment
вярно и сега го каза. това е доста очевидна моя грешка, тъй като байтовете работят само върху низове, а не върху шестнадесетични низове.   -  person Darren Rogan    schedule 08.05.2013
comment
XOR_byte_strings([m_hex_string].pack('H*'),[m_XOR_string].pack('H*'))   -  person Darren Rogan    schedule 08.05.2013
comment
Това отговор ли е, или пояснение на въпроса? Ако това е отговор, трябва да го публикувате като такъв (с обяснения и други подобни, ако е възможно)   -  person John Dvorak    schedule 08.05.2013
comment
Не можах да публикувам отговор на собствения си въпрос в рамките на 6 часа. Това беше преобразуването на шестнадесетичния низ в низ с помощта на pack. Отговорът по-долу дава по-ясен отговор. Благодаря   -  person Darren Rogan    schedule 08.05.2013


Отговори (1)


Както вече беше казано в коментарите, bytes не взема предвид шестнадесетичния формат, а просто връща целочислените стойности за "1", "2", "4", "f" и т.н. Можете да конвертирате шестнадесетичния низ с pack:

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

unpack преобразува това в байтов масив, точно като < a href="http://ruby-doc.org/core-2.0/String.html#method-i-bytes" rel="nofollow">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
person Stefan    schedule 08.05.2013