Heim > Artikel > Backend-Entwicklung > PHP verwendet Hexadezimalzahlen zum Ver- und Entschlüsseln von IDs
Vorwort
Ich bin kürzlich auf ein Problem im Projekt gestoßen. Der aktuelle Benutzer teilt einen Einladungscode mit einem Freund, nachdem er sich anhand des Einladungscodes als neuer Benutzer registriert hat. Er wird zum Untergebenen des aktuellen Benutzers. Unter bestimmten Bedingungen kann er eine Reihe von Rabatten von Benutzern niedrigerer Ebenen erhalten. Hier wird eine verschlüsselte Zeichenfolge basierend auf der ID des aktuellen Benutzers generiert, die umgekehrt entschlüsselt werden kann. Nach ständigen Tests und Anpassungen lag schließlich das Endergebnis vor. Zum Beispiel:
id = 12 code = 85U43DM
Erste Implementierung
Geben Sie zunächst den Code wie folgt ein:
/** * 加密解密用户邀请码, * @param unknown $string * @param string $action encode|decode * @return string */ function endecodeUserId($string, $action = 'encode') { $startLen = 13; $endLen = 8; $coderes = ''; #TOD 暂设定uid字符长度最大到9 if ($action=='encode') { $uidlen = strlen($string); $salt = 'yourself_code'; $codestr = $string.$salt; $encodestr = hash('md4', $codestr); $coderes = $uidlen.substr($encodestr, 5,$startLen-$uidlen).$string.substr($encodestr, -12,$endLen); $coderes = strtoupper($coderes); }elseif($action=='decode'){ $strlen = strlen($string); $uidlen = $string[0]; $coderes = substr($string, $startLen-$uidlen+1,$uidlen); } return $coderes; }
Einführung in die Idee:
Legen Sie einen Salt-Wert fest, $salt, und verketten Sie ihn mit der ID, um eine neue Zeichenfolge zu bilden. Der Salt-Wert kann später zur Sicherheitsüberprüfung des Einladungscodes verwendet werden. Führen Sie eine MD4-Verschlüsselung für die Zeichenfolge durch (dabei ist MD4 schneller und weniger sicher als MD5), rufen Sie $encodestr ab und teilen Sie die Zeichenfolge in zwei Teile auf: den ersten Teil $startLen, 13 Zeichenfolgen, und den zweiten Teil $endLen, 8 Zeichenfolgen. Mischen Sie $string, hier die übergebene ID, und $uidlen in den vorherigen Teil des Strings. Daher unterstützt es derzeit nur eine maximale Länge der ID von 9, sodass die Länge von $uidlen 1 beträgt, sodass wir am Ende eine Zeichenfolge mit der Länge 22 erhalten.
Während des Verschlüsselungsprozesses mischen wir tatsächlich den Wert der ID und die Länge der ID in die verschlüsselte Zeichenfolge. Während der Verschlüsselung finden wir die entsprechende Position basierend auf den gespeicherten Informationen, um die ID zu erhalten.
Hier stellen wir keine hohen Anforderungen an die Sicherheit. Damit das Programm schneller läuft, erfolgt keine Überprüfung bei der Entschlüsselung.
Testen, verschlüsseln Sie die ID:
echo endecodeUserId(12);
Ausgabeergebnis:
23471DC2352712F34D6780
Testen Sie, entschlüsseln Sie den Einladungscode
echo endecodeUserId('23471DC2352712F34D6780','decode');
Ausgabeergebnis:
12
Die erhaltenen Ergebnisse scheinen keine Probleme zu haben, aber im eigentlichen Test wurde ein Problem festgestellt. Dies kann bei normalen Benutzern passieren, die einen Einladungscode an sein WeChat-Handy senden und dann einen verwenden möchten Computer zum Registrieren. Aber er weiß nicht, wie er den Einladungscode von seinem Mobiltelefon auf seinen Computer übertragen soll. Zu diesem Zeitpunkt muss er den Einladungscode manuell am Computer eingeben Ziffern, und es ist immer noch eine Mischung aus Großbuchstaben und Zahlen. Er gibt die Registrierung auf.
Daher haben wir Anpassungen vorgenommen und ihn auf einen 7-stelligen Einladungscode umgestellt.
Erneut erkunden
Ist die Methode vor dem Schreiben des Artikels gekapselt oder ist es besser, sie zuerst direkt zu codieren
<?php class convert { /** * 初始数字,自定义 */ const INIT_NUM = 123456789; /** * @var 进制的基本字符串 */ private $baseChar; /** * @var 进制类型 */ private $type; /** * @var array 各进制字符串列表 */ private static $convertList = array( '32' => '0123456789ABCDEFGHJKMNPQRSTVWXYZ',//不含ILOU ); public function __construct($type='32') { $this->type = $type; $this->baseChar = self::$convertList[$type]; } /** * 公用方法,数字进行进制转换 * @param $num * @return string */ private function _idToString($num){ $str = ''; while ($num!=0){ $tmp = $num % $this->type; $str .= $this->baseChar[$tmp]; $num = intval($num/$this->type); } return $str; } /** * @desc im:十机制数转换成三十二进制数 * @param (string)$char 三十二进制数 * return 返回:十进制数 */ public function idToString($id){//10位内id 返回7位字母数字 //数组 增加备用数值 $id += self::INIT_NUM; //左补0 补齐10位 $str = str_pad($id,10,'0',STR_PAD_LEFT); //按位 拆分 4 6位(32进制 4 6位划分) $num1 = intval($str[0].$str[2].$str[6].$str[9]); $num2 = intval($str[1].$str[3].$str[4].$str[5].$str[7].$str[8]); $str1 = $str2 = ''; $str1 = $this->_idToString($num1); $str1 = strrev($str1); $str2 = $this->_idToString($num2); $str2 = strrev($str2); //4 补足 3 4位 U L return str_pad($str1,3,'U',STR_PAD_RIGHT).str_pad($str2,4,'L',STR_PAD_RIGHT); } /** * @desc im:三十二进制数转换成十机制数 * @param (string)$char 三十二进制数 * return 返回:十进制数 */ public function stringToId($str){ //1 清除 3 4 位补足位 $str1 = trim(substr($str,0,3),'U'); $str2 = trim(substr($str,3,4),'L'); $num1 = $this->_stringToId($str1); $num2 = $this->_stringToId($str2); //补位拼接 $str1 = str_pad($num1,4,'0',STR_PAD_LEFT); $str2 = str_pad($num2,6,'0',STR_PAD_LEFT); $id = ltrim($str1[0].$str2[0].$str1[1].$str2[1].$str2[2].$str2[3].$str1[2].$str2[4].$str2[5].$str1[3],'0'); //减去 备用数值 $id -= self::INIT_NUM; return $id; } /** * 公用方法字符串转数字 * @param $str * @return float|int|string */ private function _stringToId($str){ //转换为数组 $charArr = array_flip(str_split($this->baseChar)); $num = 0; for ($i=0;$i<=strlen($str)-1;$i++) { $linshi = substr($str,$i,1); if(!isset($charArr[$linshi])){ return ''; } $num += $charArr[$linshi]*pow($this->type,strlen($str)-$i-1); } return $num; } }
Einführung in die Idee
Diese Methode wurde unter der Anleitung eines seit vielen Jahren tätigen Meisters übernommen. Wandeln Sie die ID in eine 32-stellige Zeichenfolge fester Länge um und fügen Sie Ihren eigenen Algorithmus hinzu. Warum wird hier die Basis 32 anstelle anderer Basen verwendet? Das 32-Bit-System kann genügend englische Zeichen enthalten und die generierte verschlüsselte Zeichenfolge sieht standardisierter aus. Andererseits werden einige englische Zeichen, die nicht leicht zu identifizieren sind, ausgeschlossen (ILOU ist hier ausgeschlossen), also das 32-Bit-System wird anstelle von 36 Base verwendet.
Verschlüsselungsprozess, Methode idToString(). Wenn die ID am Anfang relativ klein ist, gibt es bei der Konvertierung in 32 Hexadezimalzahlen mehr Nullen, was sehr unregelmäßig erscheint, sodass ein Anfangswert INIT_NUM festgelegt wird. , dies kann angepasst werden. Entsprechend der übergebenen ID erhält man nach Addition des Anfangswertes einen Wert mit einer Länge von 10 Ziffern. Das Intervallbit dieses Wertes wird in $num1 mit einer Länge von 4 Ziffern und $num2 mit einer Länge von 6 Ziffern aufgeteilt. Die beiden Werte werden separat konvertiert. Nach der Konvertierung erhält $num1 eine Zeichenfolge mit der Länge 3. Verwenden Sie U, um den Mangel auszugleichen L, um den Mangel auszugleichen.
Die Entschlüsselung ist ein umgekehrter Vorgang. Kehren Sie einfach den Vorgang um.
Test: Generieren
$obj = new convert(32); $res1 = $obj->idToString(12);
Ergebnis:
85U43DM
Entschlüsseln:
$obj = new convert(32); $res1 = $obj->stringToId('85U43DM');
Ergebnis:
12
Zusammenfassung
Natürlich weist auch diese letzte Methode Mängel auf. Wenn beispielsweise der verschlüsselte Wert in zwei Zahlenwerte aufgeteilt wird, ist die verwendete Methode sehr unflexibel. Ich teile hier nur eine Idee und jeder ist willkommen, mich zu kritisieren und zu korrigieren.
Das obige ist der detaillierte Inhalt vonPHP verwendet Hexadezimalzahlen zum Ver- und Entschlüsseln von IDs. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!