byte manipulation in ruby
TRANSCRIPT
Byte Manipulation inRuby
Hi, I’m Harisankar P S
[email protected] | twitter.com/@coderhs
Cochin, IndiaEntrepreneur, Programmer
I am also the founder of
Ruby on Rails based software development Agency
http://redpanthers.co
“Hello World”.bytes
[72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100, 46]
LETS START WITH BASIC STUFF
97 #=> 97 in decimal (base 10)0x61 #=> 97 in hex (base 16)0141 #=> 97 in octal (base 8)0b01100001 #=> 97 in binary (base 2)
# These are all just different ways of typing the same thing:[0141, 0x61, 0b01100001, 97] #=> [97, 97, 97, 97]
Literals
97.to_s(10) #=> '97' (base 10)97.to_s(16) #=> '61' (base 16)97.to_s(8) #=> '141' (base 8)97.to_s(2) #=> '1100001' (base 2)
String/Bytes
97.chr #=> 'a''a'.ord #=> 97
Array#pack and String#unpack
Array#pack is a method for 'packing' an array into a string of bytes according to a certain format. Some examples:
hw_bytes = "Hello, world".bytes# => [72, 101, 108, 108, 111, 44, 32, 119, 111, 114, 108, 100]
# c* => Pack every element as an 8 bit signed integerhw_bytes.pack('c*') # => "Hello, world"
# s5 => Pack the first five elements as 16 bit signed integers
hw_bytes.pack('s5') # => "H\0e\0l\0l\0o\0"
# There's also an 'm' format that we can use for fast base64 encoding:["Hello, world"].pack('m0') #=> "SGVsbG8sIHdvcmxk"
http://ruby-doc.org/core-2.2.2/Array.html#method-i-pack
String#unpack takes you in the other direction: it lets you take a string in a certain binary format and 'unpack' it into an array:
# This says: read the string as a sequence 8-bit integers and "Hello, world".unpack('c*')# => [72, 101, 108, 108, 111, 44, 32, 119, 111, 114, 108, 100]
# Read as a sequence of 16 bit integers and put each"H\0e\0l\0l\0o\0,\0 \0w\0o\0r\0l\0d\0".unpack('s*')# => [72, 101, 108, 108, 111, 44, 32, 119, 111, 114, 108, 100]
# As with Array#pack, we can use the 'm' format and base64 decode"SGVsbG8sIHdvcmxk".unpack('m0') # => ["Hello, world"]
http://ruby-doc.org/core-2.2.2/String.html#method-i-unpack
XORing bits
XOR is a reversible way to 'mix' data together, and is the bread and butter operation of modern cryptography. At the logic level it means one or the other but not both and so for bits the truth table looks like this:
1 01 0 10 1 0
Like a lot of languages, in ruby the ^ operator denotes XOR. An example XOR with base 2 literals:
XOR two string
class String def xor_with(other_string) self.bytes.zip(other_string.bytes).map { |(a,b)| a ^ b }.pack('c*') endend
Chained Program to conver Base 32 string Base 64
Just for horror ;)
TABLE = “ABCDEFGHIJKLMNOPQRSTUVWXYZ234567"# Red Panthersbase_32 = ‘KJSWIICQMFXHI2DFOJZQ===='
puts [base_32.gsub('=','').chars.map { |s| TABLE.index(s) }.map { |s| s.to_s(2) }.map { |s| "0"*(5-s.length)+s}.join.chars.each_slice(8).map(&:join).map { |i| i.to_i(2) }.map { |s| s.chr }.join.strip].pack('m')
— Harisankar P S
“Thank you for listening :) ”
CREDITS
http://www.happybearsoftware.com/byte-manipulation-in-ruby.html
http://blog.bigbinary.com/2011/07/20/ruby-pack-unpack.html
http://ruby-doc.org