1

We are having some small problems when converting data from hex to integer in ruby...

We get a hardware signal, which is integer data -> converted to high and low byte, bitwise reversed -> string.

Here is a example:

Something between 0 and 75 => will be converted to "0x3938"...

But how can I convert "0x3938" back to something like 75?

I already tried:

"0x3938".to_i(16) => 14648 # wrong results (also with "0x3938".hex)

but this returns wrong values..

Any hints? I don't get this high/low byte split?

EDIT: Here are some example values, which should all result in a integer between 0 - 75. Calculation is done with joelparkerhenderson's answer..

Hex: 0x0000 - calculated integer: 0.0
Hex: 0x0000 - calculated integer: 0.0
Hex: 0x0000 - calculated integer: 0.0
Hex: 0x025d - calculated integer: 186.0
Hex: 0x0ad3 - calculated integer: 203.0
Hex: 0x0fe1 - calculated integer: 135.0
Hex: 0x1508 - calculated integer: 16.0
Hex: 0x1a8a - calculated integer: 81.0
Hex: 0x1f6e - calculated integer: 118.0
Hex: 0x244f - calculated integer: 242.0
Hex: 0x28b2 - calculated integer: 77.0
Hex: 0x2a0a - calculated integer: 80.0
Hex: 0x2aa8 - calculated integer: 21.0
Hex: 0x2ae6 - calculated integer: 103.0
Hex: 0x2add - calculated integer: 187.0
Hex: 0x2adc - calculated integer: 59.0
Hex: 0x2aea - calculated integer: 87.0
Hex: 0x2abf - calculated integer: 253.0
Hex: 0x2a87 - calculated integer: 225.0
Hex: 0x2a4a - calculated integer: 82.0
Hex: 0x2a56 - calculated integer: 106.0
Hex: 0x2a91 - calculated integer: 137.0
Hex: 0x2aee - calculated integer: 119.0
Hex: 0x2b64 - calculated integer: 38.0
Hex: 0x2f41 - calculated integer: 130.0
Hex: 0x32dc - calculated integer: 59.0
Hex: 0x341d - calculated integer: 184.0
Hex: 0x34e7 - calculated integer: 231.0
Hex: 0x35af - calculated integer: 245.0
Hex: 0x369f - calculated integer: 249.0
Hex: 0x377e - calculated integer: 126.0
Hex: 0x3873 - calculated integer: 206.0
Hex: 0x3959 - calculated integer: 154.0
Hex: 0x3a33 - calculated integer: 204.0
Hex: 0x3b4f - calculated integer: 242.0
Hex: 0x3c1b - calculated integer: 216.0
BvuRVKyUVlViVIc7
  • 11,641
  • 9
  • 59
  • 111
  • 1
    Can you add the code from the integer data onward, so it shows exactly how you're converting from the integer data to "0x3939"? – joelparkerhenderson Mar 14 '15 at 19:27
  • I updated also the values.. its just something 0-75.. the value of around 75 was just an estimation of my calculations.. – BvuRVKyUVlViVIc7 Mar 14 '15 at 19:34
  • Unfortunately not, we only receive xml data from one of our clients, which contains only these hex values... Our client just told us that is proceeded like I said with this high/low byte split... no more informations :( – BvuRVKyUVlViVIc7 Mar 14 '15 at 19:38
  • I would suggest asking the client how exactly they are generating the XML, and/or if the hardware integer data has a known width and sign (such as a 16 bit unsigned int), and the integer endian (big or little). – joelparkerhenderson Mar 14 '15 at 21:28
  • Sorry, I think i just realized that our client was not informing us correctly... YOu just have to take the first byte (f.e. 0x39 => 57), then everything works correctly... damn...! But thanks! – BvuRVKyUVlViVIc7 Mar 14 '15 at 22:53

2 Answers2

0

Here's something that may help you:

def rbit(n)
  r =  0
  8.times{|i| r = r * 2 + n[i] }
  r
end

Credit Reverse bit order of 32 bit integers by mark-hubbart

Or if you prefer bit operators, something like this:

def rbit(n)
  (((n & 0x01) << 7)
  |((n & 0x02) << 5)
  |((n & 0x04) << 3)
  |((n & 0x08) << 1)
  |((n & 0x10) >> 1)
  |((n & 0x20) >> 3)
  |((n & 0x40) >> 5)
  |((n & 0x80) >> 7))
  n
end

Credit Reverse integer bitwise without using loop by paxdiablo

Community
  • 1
  • 1
joelparkerhenderson
  • 34,808
  • 19
  • 98
  • 119
  • Looked great on the first try.. but then i realized that its not working for my other values.. see my updated question... but thanks for your help! – BvuRVKyUVlViVIc7 Mar 14 '15 at 20:11
  • Your answer was not solving my problem, but was giving me some very helpful thoughts... Therefore i mark your answer as correct. thx! – BvuRVKyUVlViVIc7 Mar 14 '15 at 22:54
0
# to convert integer into hexadecimal string
10.to_s(16) => "a"
74.to_s(16) => "4a"
75.to_a(16) => "4b" 

# to convert hexadecimal string into integer   
"4b".hex => 75
"0x4b".hex => 75    
"4b".to_i(16) => 75
"0x4b".to_i(16) => 75

So "0x3938".to_i(16) => 14648 it's not a wrong value.

For me your first method is good :)

http://ruby-doc.org/core-2.2.0/String.html#method-i-hex

  • Yeah, for me it also looked like the right method at first.. but our client says that it should work out for the values which i described above.. but this methods don't return me the expected values.. :/ – BvuRVKyUVlViVIc7 Mar 14 '15 at 20:23