5

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

2 Answers 2

16
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.

Sign up to request clarification or add additional context in comments.

1 Comment

arr.pack("c*").unpack1("H*") can also be used
7

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.