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進数に変換した.
コードクラスを定義し、まず暗号辞書、すなわち0-Zのそれぞれに対応する数値を定義し、メソッドencodeID($int,$format)のパラメータ$intは数字を表し、$formatはビット数の長さを表し、例えばencodeID(123456789,5)は数値123456789を5ビットに変換する36進数を表し、メソッドdecodeID($ids)は36進数の番号を10進数の番号に変換するために使用される.カード番号を生成するには、次のようにします.
以上のように、実際には888888(6つの8)の会員番号を表し、実際に変換した後は5桁の番号:0 J 1 VCを得ることができます.次に、都市番号と検証コードに加えて、都市番号はすでに定義されており、検証コードは一定のアルゴリズムで取得され、本例では、最初の3桁の都市番号と5桁のカード番号をmd 5暗号化し、md 5値の最初の2桁を検証コードとして取得すると、番号の後ろの2桁の検証コードが得られる.
実際の応用では、データベースから10進数の番号を得ることができ、番号が一意であることを保証し、上記のコードを組み合わせて、最終的に10ビットの重複しない会員カード番号を生成することができる.
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ビットの重複しない会員カード番号を生成することができる.