PHP実装一意番号生成(36進数の重複しない番号)

3721 ワード

膨大なデータを番号付けする場合、5桁のナンバープレート、10桁の証明書番号、注文フロー番号、短いウェブサイトなど、番号には桁数の制限があり、36進数で桁数に合致する重複しない番号を計算することができます.
0-Z(0123456789 ABCDEFGHIJKLMNOPQRSTUVWXYZ)は、アルファベットZが35を表すように、それぞれ0-35の数値を表します.これで5桁の番号が得られます.最大情報量は36の5次方で、36^5=604666176、つまり最大の5桁の番号は10進数の数字:604666176に相当します.本稿では,プレゼンテーションのために,あるクラブが10ビットの会員カード番号を発行し,会員カード番号は3ビットの都市番号+5ビットのカード番号+2ビットの検査コードからなると仮定する.都市番号は区番で表され、755が深センを表し、5桁のカード番号は36進数のカード番号からなり、後ろの2桁の検査コードは一定のアルゴリズムによって生成され、検査コードの用途はカード番号の合法性を検証することができる.これで、私たちが生成した10ビットカード番号は、最大6000万人以上の会員カード番号を満たすことができ、唯一のカード番号を繰り返さないことに相当します.
PHP実現
PHPを用いて進数変換を行い,10進数から36進数に変換した.
 
  
class Code {
    //
    private $dic = array(
        0=>'0',    1=>'1', 2=>'2', 3=>'3', 4=>'4', 5=>'5', 6=>'6', 7=>'7', 8=>'8',    
        9=>'9', 10=>'A',  11=>'B', 12=>'C', 13=>'D', 14=>'E', 15=>'F',  16=>'G',  17=>'H',    
        18=>'I',19=>'J',  20=>'K', 21=>'L',  22=>'M',  23=>'N', 24=>'O', 25=>'P', 26=>'Q',    
    27=>'R',28=>'S',  29=>'T',  30=>'U', 31=>'V',  32=>'W',  33=>'X', 34=>'Y', 35=>'Z'
    );
 
 
    public function encodeID($int, $format=8) {
        $dics = $this->dic;
        $dnum = 36; //
        $arr = array ();
        $loop = true;
        while ($loop) {
            $arr[] = $dics[bcmod($int, $dnum)];
            $int = bcdiv($int, $dnum, 0);
            if ($int == '0') {
                $loop = false;
            }
        }
        if (count($arr) < $format)
            $arr = array_pad($arr, $format, $dics[0]);
 
        return implode('', array_reverse($arr));
    }
 
    public function decodeID($ids) {
        $dics = $this->dic;
        $dnum = 36; //
        //
        $dedic = array_flip($dics);
        //
        $id = ltrim($ids, $dics[0]);
        //
        $id = strrev($id);
        $v = 0;
        for ($i = 0, $j = strlen($id); $i < $j; $i++) {
            $v = bcadd(bcmul($dedic[$id {
                $i }
            ], bcpow($dnum, $i, 0), 0), $v, 0);
        }
        return $v;
    }
 
}

コードクラスを定義し、まず暗号辞書、すなわち0-Zのそれぞれに対応する数値を定義し、メソッドencodeID($int,$format)のパラメータ$intは数字を表し、$formatはビット数の長さを表し、例えばencodeID(123456789,5)は数値123456789を5ビットに変換する36進数を表し、メソッドdecodeID($ids)は36進数の番号を10進数の番号に変換するために使用される.カード番号を生成するには、次のようにします.
 
  
$code = new Code();
$card_no = $code->encodeID(888888,5);

以上のように、実際には888888(6つの8)の会員番号を表し、実際に変換した後は5桁の番号:0 J 1 VCを得ることができます.次に、都市番号と検証コードに加えて、都市番号はすでに定義されており、検証コードは一定のアルゴリズムで取得され、本例では、最初の3桁の都市番号と5桁のカード番号をmd 5暗号化し、md 5値の最初の2桁を検証コードとして取得すると、番号の後ろの2桁の検証コードが得られる.
 
  
$card_pre = '755';
$card_vc = substr(md5($card_pre.$card_no),0,2);
$card_vc = strtoupper($card_vc);
echo $card_pre.$card_no.$card_vc;

実際の応用では、データベースから10進数の番号を得ることができ、番号が一意であることを保証し、上記のコードを組み合わせて、最終的に10ビットの重複しない会員カード番号を生成することができる.