天天看點

Ruby中對應PHP的hex2bin和bin2hex方法

今天觀摩了網上PHP大師破譯系統資料庫Navicat連接配接中儲存的資料庫密碼,現實中也遇到了這樣的尴尬,由于本地沒有PHP運作環境,線上執行的方法畢竟把密碼POST出去了,感覺欠妥,打算使用其它語言移植一段代碼備日後使用。在移植過程中遇到Ruby沒有現成的标題中提到的兩個方法,而需要使用pack和unpack來完成工作,恰巧這兩個方法的官方文檔描述是非常晦澀的,不動手嘗試完全不能了解它在說什麼,下面放上一段加密和解密的方法,然後在記錄下pack和unpack在處理十六進制字元串時的用法。

#encoding:utf-8

require 'openssl'

def aes_encrypt(key, iv, plain_string)
  aes = OpenSSL::Cipher::AES.new(128, :CBC)
  aes.encrypt
  aes.key = key
  aes.iv = iv
  txt = aes.update(plain_string) << aes.final
  txt.unpack('H*')[0].upcase
end

def aes_decrypt(key, iv, dicrypted_string)
  aes = OpenSSL::Cipher::AES.new(128, :CBC)
  aes.decrypt
  aes.key = key
  aes.iv = iv
  aes.update([dicrypted_string].pack('H*')) << aes.final
end
           

這兩段代碼是抄來的,隻增加了aes的iv參數和修改一些參數的命名。

比如字母'a'的ascii碼是0x61,要把串'616161'翻譯成'aaa'需要做以下的操作:先把這個串塞入Array對象,然後用Array的pack方法把元素連接配接起來,H*表示單位元組hex高4bit在前,低4bit在後。對應的有h*,和字序Little-Endian和Big-Endian類似,隻是以半個位元組為機關。

#hex2bin
irb(main):001:0> a = Array.new
=> []
irb(main):002:0> a << '616161'
=> ["616161"]
irb(main):003:0> a.pack('H*')
=> "aaa"
           

反過來要把'aaa'串翻譯成'616161',需要借助String對象的unpack方法。

#bin2hex
irb(main):004:0> b='aaa'
=> "aaa"
irb(main):005:0> b.unpack('H*')
=> ["616161"]
           

這兩個方法很彪悍,隻是文檔描述太過簡單,示例又缺乏代表性,隻能自己嘗試着看執行效果。