2

我一直在寻找 phpclasses,谷歌,但还找不到一个简单的编码类,它允许我将字符串(唯一数字)编码/加密为唯一的短字母数字代码,然后将其解码/解密回原始数字。主要目的是在应用程序中对 facebook 用户 ID 进行编码。

例子:

1544686448 => EHO1RUJF0G => 1544686448  
1063344785 => ABN2BDOIEH => 1063344785  
50124558 => POKDJMFNE => 50124558

我很确定那里一定存在一个简单的,并且不能花整个月做我自己的。谢谢

4

3 回答 3

2

这是 XTEA 加密算法的 PHP 实现。

<?php    
/**
 * This class uses the Tiny Encryption Algorithm (TEA) to provide a fast,
 * simple method to encrypt/decrypt data.
 * 
 * Usage:
 * <?php
 * require_once('xtea.php');
 * // The salt is usually created when a user logs in.
 * $salt = md5(gmdate('Y-m-d H:i:s')); // Generate a better random salt than this!
 *  $_SESSION['salt'] = $salt;
 * // Then we create the xtea object with the previously created $_SESSION['salt'].
 * $xtea = new xtea($_SESSION['salt']);
 * $encrypted_data = $xtea->encrypt('Whatever data you want to encrypt');
 * $decrypted_data = trim($xtea->decrypt($encrypted_data));
 * ?>
 *
 * @see http://en.wikipedia.org/wiki/Tiny_Encryption_Algorithm
 */
class xtea{
    //Private members.
    /**
     * The salt to be used in encrypting/decrypting data.
     * @var string
     */
    private $key;

    /**
     * Flag indicating whether to use CBC or ECB mode. Normally CBC mode would be the right choice so this member defaults to TRUE.
     * @var boolean
     */
    private $cbc = TRUE;

    /**
     * Constructor.
     * @param string $key A string of characters to be used as a salt.
     */
    function __construct($key){
        $this->key_setup($key);
    }

    /**
     * Verify the implementation of the Blowfish algorithm.
     *
     * @return boolean TRUE if the implementation is correct, FALSE otherwise.
     */
    public function check_implementation(){
        $xtea = new xtea("");
        $vectors = array(
            array(array(0x00000000,0x00000000,0x00000000,0x00000000), array(0x41414141,0x41414141), array(0xed23375a,0x821a8c2d)),
            array(array(0x00010203,0x04050607,0x08090a0b,0x0c0d0e0f), array(0x41424344,0x45464748), array(0x497df3d0,0x72612cb5)),
        );

        //Correct implementation?
        $correct = true;

        //Test vectors, see http://www.schneier.com/code/vectors.txt
        foreach($vectors AS $vector){
            $key = $vector[0];
            $plain = $vector[1];
            $cipher = $vector[2];

            $xtea->key_setup($key);
            $return = $xtea->block_encrypt($vector[1][0],$vector[1][1]);

            if((int)$return[0] != (int)$cipher[0] || (int)$return[1] != (int)$cipher[1]){
                $correct = false;
            }
        }
        return $correct;
    }

    /**
     * Decrypt data. Note: all trailing spaces that might have been added in the encrypt method are trimmed.
     *
     * @param string $text The data to be decrypted.
     * @return string The decrypted data.
     */
    public function decrypt($text){
        $plain = array();
        $cipher = $this->_str2long(base64_decode($text));

        if($this->cbc){
            $i = 2; //Message start at second block
        }else{
            $i = 0; //Message start at first block
        }

        for($i; $i<count($cipher); $i+=2){
            $return = $this->block_decrypt($cipher[$i],$cipher[$i+1]);

            //XORed $return with the previous ciphertext
            if($this->cbc){
                $plain[] = array($return[0]^$cipher[$i-2],$return[1]^$cipher[$i-1]);
            }else{
                //EBC Mode
                $plain[] = $return;
            }
        }

        $output = '';
        for($i = 0; $i<count($plain); $i++){
            $output .= $this->_long2str($plain[$i][0]);
            $output .= $this->_long2str($plain[$i][1]);
        }
        return rtrim($output);
    }

    /**
     * Encrypt some data and return it base64 encoded.
     *
     * @param string $text The data to be encrypted.
     * @return string The encrypted data
     * @see base64_encode
     */
    public function encrypt($text){
        $n = strlen($text);
        if($n%8 != 0){
            $lng = ($n+(8-($n%8)));
        }else{
            $lng = 0;
        }

        $text = str_pad($text, $lng, ' ');
        $text = $this->_str2long($text);

        //Initialization vector: IV
        if($this->cbc){
            $cipher[0][0] = time();
            $cipher[0][1] = (double)microtime()*1000000;
        }

        $a = 1;
        for($i = 0; $i<count($text); $i+=2){
            if($this->cbc){
                //$text is XORed with the previous ciphertext
                $text[$i] ^= $cipher[$a-1][0];
                $text[$i+1] ^= $cipher[$a-1][1];
            }
            $cipher[] = $this->block_encrypt($text[$i],$text[$i+1]);
            $a++;
        }

        $output = "";
        for($i = 0; $i<count($cipher); $i++){
            $output .= $this->_long2str($cipher[$i][0]);
            $output .= $this->_long2str($cipher[$i][1]);
        }
        return base64_encode($output);
    }

    /**
     * Decrypt a block of data.
     *
     * @param integer $y
     * @param integer $z
     * @return array The decrypted block of data.
     */
    private function block_decrypt($y, $z){
        $delta=0x9e3779b9;
        $sum=0xC6EF3720;
        $n=32;

        /* start cycle */
        for ($i=0; $i<32; $i++){
            $z      = $this->_add($z, -($this->_add($y << 4 ^ $this->_rshift($y, 5), $y) ^ $this->_add($sum, $this->key[$this->_rshift($sum, 11) & 3])));
            $sum    = $this->_add($sum, -$delta);
            $y      = $this->_add($y, -($this->_add($z << 4 ^ $this->_rshift($z, 5), $z) ^ $this->_add($sum, $this->key[$sum & 3])));
        }
        /* end cycle */
        return array($y,$z);
    }

    /**
     * Encrypt a block of data.
     *
     * @param integer $y
     * @param integer $z
     * @return array The encrypted block of data.
     */
    private function block_encrypt($y, $z){
        $sum=0;
        $delta=0x9e3779b9;

        /* start cycle */
        for ($i=0; $i<32; $i++){
            $y      = $this->_add($y, $this->_add($z << 4 ^ $this->_rshift($z, 5), $z) ^ $this->_add($sum, $this->key[$sum & 3]));
            $sum    = $this->_add($sum, $delta);
            $z      = $this->_add($z, $this->_add($y << 4 ^ $this->_rshift($y, 5), $y) ^ $this->_add($sum, $this->key[$this->_rshift($sum, 11) & 3]));
        }

        /* end cycle */
        $v[0]=$y;
        $v[1]=$z;

        return array($y,$z);
    }

    /**
     * Set up the salt.
     *
     * @param string $key The salt to be used in encrypting/decrypting data.
     */
    private function key_setup($key){
        if(is_array($key)){
            $this->key = $key;
        }else if(isset($key) && !empty($key)){
            $this->key = $this->_str2long(str_pad($key, 16, $key));
        }else{
            $this->key = array(0,0,0,0);
        }
    }

    /**
     * I have no idea what this function actually does. :-)
     *
     * @param integer $i1
     * @param integer $i2
     * @return integer The manipulated data.
     */
    private function _add($i1, $i2){
        $result = 0.0;

        foreach (func_get_args() as $value){
            // remove sign if necessary
            if (0.0 > $value){
                $value -= 1.0 + 0xffffffff;
            }
            $result += $value;
        }

        // convert to 32 bits
        if (0xffffffff < $result || -0xffffffff > $result){
            $result = fmod($result, 0xffffffff + 1);
        }

        // convert to signed integer
        if (0x7fffffff < $result){
            $result -= 0xffffffff + 1.0;
        }elseif (-0x80000000 > $result){
            $result += 0xffffffff + 1.0;
        }
        return $result;
    }

    //Convert a longinteger into a string
    /**
     * Convert a long integer into a string.
     *
     * @param integer $l The long integer to be converted.
     * @return string The converted integer.
     */
    private function _long2str($l){
        return pack('N', $l);
    }

    /**
     * Right shift some data.
     *
     * @param integer $integer
     * @param integer $n
     * @return integer The shifted data.
     */
    private function _rshift($integer, $n){
        // convert to 32 bits
        if (0xffffffff < $integer || -0xffffffff > $integer){
            $integer = fmod($integer, 0xffffffff + 1);
        }

        // convert to unsigned integer
        if (0x7fffffff < $integer){
            $integer -= 0xffffffff + 1.0;
        }elseif (-0x80000000 > $integer){
            $integer += 0xffffffff + 1.0;
        }

        // do right shift
            if (0 > $integer){
                $integer &= 0x7fffffff;         // remove sign bit before shift
                $integer >>= $n;                    // right shift
                $integer |= 1 << (31 - $n); // set shifted sign bit
            }else{
                $integer >>= $n;                    // use normal right shift
            }
        return $integer;
    }

    /**
     * Convert a string into a long integer
     *
     * @param string The string to be converted to a long integer.
     * @return integer The converted string.
     */
    private function _str2long($data){
        $n = strlen($data);
        $tmp = unpack('N*', $data);
        $data_long = array();
        $j = 0;

        foreach ($tmp as $value){
            $data_long[$j++] = $value;
        }
        return $data_long;
    }
}
?>
于 2013-04-08T18:45:14.110 回答
1

感谢 Benny Hill,我找到了解决方案。使用 Base36 转换

一个例子:

使用 PHP 进行 Base36 编码和解码

于 2013-04-08T20:19:12.847 回答
0

我发现了有趣的功能:

function dsCrypt($input,$decrypt=false) {
    $o = $s1 = $s2 = array();
    $basea = array('?','(','@',';','$','#',"]","&",'*'); // base symbol set
    $basea = array_merge($basea, range('a','z'), range('A','Z'), range(0,9) );
    $basea = array_merge($basea, array('!',')','_','+','|','%','/','[','.',' ') );
    $dimension=9;
    for($i=0;$i<$dimension;$i++) { // create Squares
        for($j=0;$j<$dimension;$j++) {
            $s1[$i][$j] = $basea[$i*$dimension+$j];
            $s2[$i][$j] = str_rot13($basea[($dimension*$dimension-1) - ($i*$dimension+$j)]);
        }
    }
    unset($basea);
    $m = floor(strlen($input)/2)*2;
    $symbl = $m==strlen($input) ? '':$input[strlen($input)-1];
    $al = array();
    for ($ii=0; $ii<$m; $ii+=2) {
        $symb1 = $symbn1 = strval($input[$ii]);
        $symb2 = $symbn2 = strval($input[$ii+1]);
        $a1 = $a2 = array();
        for($i=0;$i<$dimension;$i++) {
            for($j=0;$j<$dimension;$j++) {
                if ($decrypt) {
                    if ($symb1===strval($s2[$i][$j]) ) $a1=array($i,$j);
                    if ($symb2===strval($s1[$i][$j]) ) $a2=array($i,$j);
                    if (!empty($symbl) && $symbl===strval($s2[$i][$j])) $al=array($i,$j);
                }
                else {
                    if ($symb1===strval($s1[$i][$j]) ) $a1=array($i,$j);
                    if ($symb2===strval($s2[$i][$j]) ) $a2=array($i,$j);
                    if (!empty($symbl) && $symbl===strval($s1[$i][$j])) $al=array($i,$j);
                }
            }
        }
        if (sizeof($a1) && sizeof($a2)) {
            $symbn1 = $decrypt ? $s1[$a1[0]][$a2[1]] : $s2[$a1[0]][$a2[1]];
            $symbn2 = $decrypt ? $s2[$a2[0]][$a1[1]] : $s1[$a2[0]][$a1[1]];
        }
        $o[] = $symbn1.$symbn2;
    }
    if (!empty($symbl) && sizeof($al))
        $o[] = $decrypt ? $s1[$al[1]][$al[0]] : $s2[$al[1]][$al[0]];
    return implode('',$o);
}

例子:

$test = "Some test string";
$encoded = dsCrypt($test);
echo $encoded; //output g!1W]!76F(D2JSHO
echo dsCrypt($encoded, true); //output Some test string

资料来源:http ://habrahabr.ru/post/61309/

于 2013-04-08T18:42:39.030 回答