How to convert to big endian to ruby

I have a string in little-endian order, like a hex encoded string

000000020597ba1f0cd423b2a3abb0259a54ee5f783077a4ad45fb6200000218 000000008348d1339e6797e2b15e9a3f2fb7da08768e99f02727e4227e02903e 43a42b31511553101a051f3c0000000000000080000000000000000000000000 0000000000000000000000000000000000000000000000000000000080020000 

I would like bytes to display every 32-bit fragment from little-endian to big-endian, which led to

 020000001fba9705b223d40c25b0aba35fee549aa477307862fb45ad18020000 0000000033d14883e297679e3f9a5eb108dab72ff0998e7622e427273e90027e 312ba443105315513c1f051a0000000080000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000280 

I tried several approaches, but did not get it to work. It would be great if someone could show an approximate implementation.

Greetings.

+4
source share
3 answers

You can also use pack and unpack :

  • hex decoding first
  • then convert to 32 bit integers in small endian
  • encoding these integers with a large entic
  • encoding the result in hexadecimal format.

In code:

 s = "000000020597ba1f0cd4..." [s].pack('H*').unpack('N*').pack('V*').unpack('H*') # => "020000001fba9705b223..." 
+4
source

In addition to Łukasz Niemier's answer, you can let scan handle the grouping in one step:

 hex_string = "000000020597ba1f..." hex_string.scan(/(..)(..)(..)(..)/).map(&:reverse).join # => "020000001fba9705..." 
  • scan(/(..)(..)(..)(..)/) splits the string into groups of 4 x 2 bytes:

     [["00", "00", "00", "02"], ["05", "97", "ba", "1f"], ... ] 
  • map(&:reverse) changes internal 2-byte arrays:

     [["02", "00", "00", "00"], ["1f", "ba", "97", "05"], ... ] 
  • join joins all elements of an array

     "020000001fba9705..." 
+3
source

My approach is to split the line for every 8 characters:

 hexes = str.scan(/.{8}/) 

then match them to change endiannes by changing all 2 characters:

 big = hexes.map { |hex| hex.scan(/.{2}/).reverse.join('') } 

and then attach them all together

 str = big.join('') 

Example pry session:

 [23] pry(main)> str => "000000020597ba1f0cd423b2a3abb0259a54ee5f783077a4ad45fb6200000218000000008348d1339e6797e2b15e9a3f2fb7da08768e99f02727e4227e02903e43a42b31511553101a051f3c00000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000" [24] pry(main)> str.scan(/.{8}/).map { |s| s.scan(/.{2}/).reverse.join('') }.join('') => "020000001fba9705b223d40c25b0aba35fee549aa477307862fb45ad180200000000000033d14883e297679e3f9a5eb108dab72ff0998e7622e427273e90027e312ba443105315513c1f051a00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000280" 

Or an improvement on @ Stefan's answer:

 hex_string.scan(/(..){4}/).msp(&:reverse).join('') # remember that anybody can change $, variable 

Strike>

+2
source

All Articles