I am trying to convert the following byte array to hexadecimal;
[1, 1, 65, -50, 6, 104, -91, -70, -100, 119, -100, 123, 52, -109, -33, 45, -14, 86, -105, -97, -115, 16]
The result should be;
010141CE0668A5BA9C779C7B3493DF2DF256979F8D10
Here is my current attempt;
item.getProperties["Mapi-Conversation-Index"].to_a.map {|s| s.to_s(16)}.join()
But my output is: 010141-320668-5b-46-6477-647b34-6d-212d-e56-69-61-7310
arr = [1, 1, 65, -50, 6, 104, -91, -70, -100, 119, -100, 123, 52, -109, -33, 45, -14, 86]
arr.pack("c*").unpack("H*").first
#=> "010141ce0668a5ba9c779c7b3493df2df256"
See Array#pack and String#unpack.
The argument "c"
for pack
specifies an 8-bit signed integer. The argument "H"
for unpack
specifies "hex string (high nibble first)". The asterisk at the end of each directive specifies that "c"
applies to all elements of arr
and "H"
applies to all characters of the string produced by pack
.
Note that
arr.pack("c*")
#=> "\x01\x01A\xCE\x06h\xA5\xBA\x9Cw\x9C{4\x93\xDF-\xF2V"
and
arr.pack("c*").unpack("H*")
#=> ["010141ce0668a5ba9c779c7b3493df2df256"]
which is why first
is needed to extract the string.
This works:
[1, 1, 65, -50].map { |n| '%02X' % (n & 0xFF) }.join
The %02X
format specifier makes a 2-character-wide hex number, padded with 0
digits. The & 0xFF
is necessary to convert your negative numbers into the standard 0 through 255 range that people usually use when talking about byte values.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With