LoginSignup
9
4

More than 5 years have passed since last update.

Ruby で整数を可逆スクランブルする(適当)

Posted at

Ruby で適当な連番 ID をちょっと推測しづらいぐらいでスクランブルしたい時のためのコード。Rails なんかは標準で連番 ID なので、ちょっとした ID 隠しをしたい時向けです。あんまりしっかり検証してないので、信用しすぎは禁物。

めちゃくちゃ厳密に隠したい訳ではなく、ロジック知ってないと推測しずらいな程度で、かつ桁数をそこまで気にしたくない、というような用途にしか使えません。ただ、 Salt 値を足したりすることで推測難易度はいくらかあげられるかと思います。

module Scrambler
  MINIMUM_SCRAMBLE_DIGIT = 20
  SCRAMBLE_BASE = 36

  def self.scramble(id)
    reversed = id.to_s.rjust(MINIMUM_SCRAMBLE_DIGIT, '0').reverse
    "1#{reversed}".to_i.to_s(SCRAMBLE_BASE)
  end

  def self.unscramble(hash)
    reversed = hash.to_i(SCRAMBLE_BASE).to_s.reverse
    reversed[0, reversed.length - 1].to_i
  end
end

やってることは単純で

  1. 数値を文字列にして最低桁数(MINIMUM_SCRAMBLE_DIGIT)分0埋めする
  2. ひっくり返す
  3. ひっくり返した先頭に 1 を追加(これをしないと 100 なんかが不可逆になる)
  4. その文字列を数値 -> 36進数で変換

というような手順。これを実行すると、

1 => n7q81nvr7zz7k
2 => pbpc1tbqf9slc
3 => rfog1yrpmjlz4
4 => tjnk247ottfcw
5 => vnmo29no138qo
6 => xrls2f3n8d24g
7 => zvkw2kjmfmvi8
8 => 11zk02pzlmwow0
9 => 143j42vfku6i9s
10 => lbcmfxdrxuqrk

みたいな具合になるので、多分そこそこ使い勝手がいいんじゃないかな。割とわからない感じだし。 MINIMUM_SCRAMBLE_DIGIT を変えることで最小桁数が変わるので、生成後の文字の長さも変わります。

MINIMUM_SCRAMBLE_DIGIT = 10
1 => 51x46bk
2 => 5ighn9c
3 => 5yzv474
4 => 6fj8l4w
5 => 6w2m22o
6 => 7clzj0g
7 => 7t5czy8
8 => 89oqgw0
9 => 8q83xts
10 => 4n1a1vk

変わるけど、復号化のロジックはそのまま使いまわせるので、そんなに困らない。また、ひっくり返した後に付与する 10 でなければなんでもいいので、それこそ擬似乱数でも構わないです。そうなると scramble 書ける度に違う ID に見えるような発行の仕方になるので、それはそれで使いみちがありそう。

という小ネタでした。おしまい。

9
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
4