2015-03-17

Ruby : Integer Obfuscator

最近在做數字攪亂器,類似 user_id : ATM(虛擬帳號互轉),簡單的來說要1:1的攪亂,找了幾篇文章才找到學理解釋,類似這篇

http://ericlippert.com/2013/11/14/a-practical-use-of-multiplicative-inverses/

大概就是需要三個數字,MAX[int] & 質數A[int:coprime] & inverse(MAX & 質數A)[int:coprime],最後一個數字可以算出來,MAX則為需求,類似99999999,質數A就到處亂找了,類似2147483647 (2^32 - 1)

so~ 以上,先列出inverse的寫法
http://en.wikipedia.org/wiki/Extended_Euclidean_algorithm
  MAX = 99999999
  COPRIME = 2147483647

  def inverse(a, n)
    t = 0 ; newt = 1
    r = n ; newr = a
    while newr != 0
      quotient = r / newr
      t , newt = newt , t - quotient * newt
      r , newr = newr , r - quotient * newr
    end
    return "a is not invertible" if r > 1
    return t < 0 ? t + n : t
  end

  COPRIME_INVERSE = inverse(COPRIME , MAX) #=> 52892335
再來其實就是使用了,使用的話就非常簡單,類似
  def source_encode(source)
    return source.to_i * COPRIME % MAX
  end
  def source_decode(source)
    return source.to_i * COPRIME_INVERSE % MAX
  end

  source_encode(1) #=> 47483668
  #...

當然你可以用小數字去測試這是否是正確的,類似 MAX = 10

  MAX = 10
  COPRIME = 2147483647
  COPRIME_INVERSE = inverse(COPRIME , MAX) #=> 3
  (MAX * 2).times do |source|
    puts "#{source} : #{source_encode(source)} : #{source_decode(source_encode(source))}"
  end
  #=> 0 : 0 : 0
  #=> 1 : 7 : 1
  #=> 2 : 4 : 2
  #=> 3 : 1 : 3
  #=> 4 : 8 : 4
  #=> 5 : 5 : 5
  #=> 6 : 2 : 6
  #=> 7 : 9 : 7
  #=> 8 : 6 : 8
  #=> 9 : 3 : 9
  #=> 10 : 0 : 0
  #=> 11 : 7 : 1
  #=> 12 : 4 : 2
  #=> 13 : 1 : 3
  #=> 14 : 8 : 4
  #=> 15 : 5 : 5
  #=> 16 : 2 : 6
  #=> 17 : 9 : 7
  #=> 18 : 6 : 8
  #=> 19 : 3 : 9

這邊其實多了示範在 MAX * 2 在顯示如果超過會怎樣,你會發現會循環,其實某種程度上這非常方便,類似前面再加上英文字母就可以多軌同時進行且自動切割好好,而如果你怕人破解,請隨機找個質數之類的,會建議大點,anyway以上 & (rock)

沒有留言:

張貼留言