Heim > Backend-Entwicklung > PHP-Tutorial > PHP verwendet Hexadezimalzahlen zum Ver- und Entschlüsseln von IDs

PHP verwendet Hexadezimalzahlen zum Ver- und Entschlüsseln von IDs

藏色散人
Freigeben: 2023-04-07 20:06:01
nach vorne
3688 Leute haben es durchsucht

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
Nach dem Login kopieren

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;
}
Nach dem Login kopieren

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);
Nach dem Login kopieren

Ausgabeergebnis:

23471DC2352712F34D6780
Nach dem Login kopieren

Testen Sie, entschlüsseln Sie den Einladungscode

echo endecodeUserId('23471DC2352712F34D6780','decode');
Nach dem Login kopieren

Ausgabeergebnis:

12
Nach dem Login kopieren
Nach dem Login kopieren

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(
        &#39;32&#39; => &#39;0123456789ABCDEFGHJKMNPQRSTVWXYZ&#39;,//不含ILOU
    );
    public function __construct($type=&#39;32&#39;)
    {
        $this->type = $type;
        $this->baseChar = self::$convertList[$type];
    }
    /**
     * 公用方法,数字进行进制转换
     * @param $num
     * @return string
     */
    private function _idToString($num){
        $str = &#39;&#39;;
        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,&#39;0&#39;,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 = &#39;&#39;;
        $str1 = $this->_idToString($num1);
        $str1 = strrev($str1);
        $str2 = $this->_idToString($num2);
        $str2 = strrev($str2);
        //4 补足 3 4位 U L
        return str_pad($str1,3,&#39;U&#39;,STR_PAD_RIGHT).str_pad($str2,4,&#39;L&#39;,STR_PAD_RIGHT);
    }
    /**
     * @desc  im:三十二进制数转换成十机制数
     * @param (string)$char 三十二进制数
     * return 返回:十进制数
     */
    public function stringToId($str){
        //1 清除 3 4 位补足位
        $str1 = trim(substr($str,0,3),&#39;U&#39;);
        $str2 = trim(substr($str,3,4),&#39;L&#39;);
        $num1 = $this->_stringToId($str1);
        $num2 = $this->_stringToId($str2);
        //补位拼接
        $str1 = str_pad($num1,4,&#39;0&#39;,STR_PAD_LEFT);
        $str2 = str_pad($num2,6,&#39;0&#39;,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],&#39;0&#39;);
        //减去 备用数值
        $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 &#39;&#39;;
            }
            $num += $charArr[$linshi]*pow($this->type,strlen($str)-$i-1);
        }
        return $num;
    }
}
Nach dem Login kopieren

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);
Nach dem Login kopieren

Ergebnis:

85U43DM
Nach dem Login kopieren

Entschlüsseln:

$obj = new convert(32);
$res1 = $obj->stringToId(&#39;85U43DM&#39;);
Nach dem Login kopieren

Ergebnis:

12
Nach dem Login kopieren
Nach dem Login kopieren

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!

Verwandte Etiketten:
php
Quelle:segmentfault.com
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage