Advertisement
Guest User

Untitled

a guest
Apr 24th, 2019
68
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 10.54 KB | None | 0 0
  1. <?php
  2. /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
  3.  
  4. /**
  5.  * PHP implementation of XXTEA encryption algorithm.
  6.  *
  7.  * XXTEA is a secure and fast encryption algorithm, suitable for web
  8.  * development.
  9.  *
  10.  * PHP versions 4 and 5
  11.  *
  12.  * LICENSE: This library is free software; you can redistribute it
  13.  * and/or modify it under the terms of the GNU Lesser General Public
  14.  * License as published by the Free Software Foundation; either
  15.  * version 2.1 of the License, or (at your option) any later version.
  16.  *
  17.  * This library is distributed in the hope that it will be useful,
  18.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  19.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  20.  * Lesser General Public License for more details.
  21.  *
  22.  * You should have received a copy of the GNU Lesser General Public
  23.  * License along with this library; if not, write to the Free Software
  24.  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
  25.  * MA 02110-1301 USA.
  26.  *
  27.  * @category   Encryption
  28.  * @package    Crypt_XXTEA
  29.  * @author     Wudi Liu <wudicgi@gmail.com>
  30.  * @author     Ma Bingyao <andot@ujn.edu.cn>
  31.  * @copyright  2005-2008 Coolcode.CN
  32.  * @license    http://www.gnu.org/copyleft/lesser.html  LGPL License 2.1
  33.  * @version    CVS: $Id: XXTEA.php,v 1.3 2008/03/06 11:38:45 wudicgi Exp $
  34.  * @link       http://pear.php.net/package/Crypt_XXTEA
  35.  */
  36.  
  37. /**
  38.  * Needed for error handling
  39.  */
  40. require_once 'PEAR.php';
  41.  
  42. // {{{ constants
  43.  
  44. define('CRYPT_XXTEA_DELTA', 0x9E3779B9);
  45.  
  46. // }}}
  47.  
  48. /**
  49.  * The main class
  50.  *
  51.  * @category   Encryption
  52.  * @package    Crypt_XXTEA
  53.  * @author     Wudi Liu <wudicgi@gmail.com>
  54.  * @author     Ma Bingyao <andot@ujn.edu.cn>
  55.  * @copyright  2005-2008 Coolcode.CN
  56.  * @license    http://www.gnu.org/copyleft/lesser.html  LGPL License 2.1
  57.  * @version    Release: 0.9.0
  58.  * @link       http://pear.php.net/package/Crypt_XXTEA
  59.  */
  60. class Crypt_XXTEA {
  61.     // {{{ properties
  62.  
  63.     /**
  64.      * The long integer array of secret key
  65.      *
  66.      * @access private
  67.      *
  68.      * @var array
  69.      */
  70.     var $_key;
  71.  
  72.     // }}}
  73.  
  74.     // {{{ setKey()
  75.  
  76.     /**
  77.      * Sets the secret key
  78.      *
  79.      * The key must be non-empty, and not more than 16 characters or 4 long values
  80.      *
  81.      * @access public
  82.      *
  83.      * @param mixed $key  the secret key (string or long integer array)
  84.      *
  85.      * @return bool  true on success, PEAR_Error on failure
  86.      */
  87.     function setKey($key) {
  88.         if (is_string($key)) {
  89.             $k = $this->_str2long($key, false);
  90.         } elseif (is_array($key)) {
  91.             $k = $key;
  92.         } else {
  93.             return PEAR::raiseError('The secret key must be a string or long integer array.');
  94.         }
  95.         if (count($k) > 4) {
  96.             return PEAR::raiseError('The secret key cannot be more than 16 characters or 4 long values.');
  97.         } elseif (count($k) == 0) {
  98.             return PEAR::raiseError('The secret key cannot be empty.');
  99.         } elseif (count($k) < 4) {
  100.             for ($i = count($k); $i < 4; $i++) {
  101.                 $k[$i] = 0;
  102.             }
  103.         }
  104.         $this->_key = $k;
  105.         return true;
  106.     }
  107.  
  108.     // }}}
  109.  
  110.     // {{{ encrypt()
  111.  
  112.     /**
  113.      * Encrypts a plain text
  114.      *
  115.      * As the XXTEA encryption algorithm is designed for encrypting and decrypting
  116.      * the long integer array type of data, there is not a standard that defines
  117.      * how to convert between long integer array and text or binary data for it.
  118.      * So this package provides the ability to encrypt and decrypt the long integer
  119.      * arrays directly to satisfy the requirement for working with other
  120.      * implementations. And at the same time, for convenience, it also provides
  121.      * the ability to process strings, which uses its own method to group the text
  122.      * into array.
  123.      *
  124.      * @access public
  125.      *
  126.      * @param mixed $plaintext  the plain text (string or long integer array)
  127.      *
  128.      * @return mixed  the cipher text as the same type as the parameter $plaintext
  129.      *                on success, PEAR_Error on failure
  130.      */
  131.     function encrypt($plaintext) {
  132.         if ($this->_key == null) {
  133.             return PEAR::raiseError('Secret key is undefined.');
  134.         }
  135.         if (is_string($plaintext)) {
  136.             return $this->_encryptString($plaintext);
  137.         } elseif (is_array($plaintext)) {
  138.             return $this->_encryptArray($plaintext);
  139.         } else {
  140.             return PEAR::raiseError('The plain text must be a string or long integer array.');
  141.         }
  142.     }
  143.  
  144.     // }}}
  145.  
  146.     // {{{ decrypt()
  147.  
  148.     /**
  149.      * Decrypts a cipher text
  150.      *
  151.      * @access public
  152.      *
  153.      * @param mixed $chipertext  the cipher text (string or long integer array)
  154.      *
  155.      * @return mixed  the plain text as the same type as the parameter $chipertext
  156.      *                on success, PEAR_Error on failure
  157.      */
  158.     function decrypt($chipertext) {
  159.         if ($this->_key == null) {
  160.             return PEAR::raiseError('Secret key is undefined.');
  161.         }
  162.         if (is_string($chipertext)) {
  163.             return $this->_decryptString($chipertext);
  164.         } elseif (is_array($chipertext)) {
  165.             return $this->_decryptArray($chipertext);
  166.         } else {
  167.             return PEAR::raiseError('The chiper text must be a string or long integer array.');
  168.         }
  169.     }
  170.  
  171.     // }}}
  172.  
  173.     // {{{ _encryptString()
  174.  
  175.     /**
  176.      * Encrypts a string
  177.      *
  178.      * @access private
  179.      *
  180.      * @param string $str  the string to encrypt
  181.      *
  182.      * @return string  the string type of the cipher text on success,
  183.      *                 PEAR_Error on failure
  184.      */
  185.     function _encryptString($str) {
  186.         if ($str == '') {
  187.             return '';
  188.         }
  189.         $v = $this->_str2long($str, true);
  190.         $v = $this->_encryptArray($v);
  191.         return $this->_long2str($v, false);
  192.     }
  193.  
  194.     // }}}
  195.  
  196.     // {{{ _encryptArray()
  197.  
  198.     /**
  199.      * Encrypts a long integer array
  200.      *
  201.      * @access private
  202.      *
  203.      * @param array $v  the long integer array to encrypt
  204.      *
  205.      * @return array  the array type of the cipher text on success,
  206.      *                PEAR_Error on failure
  207.      */
  208.     function _encryptArray($v) {
  209.         $n = count($v) - 1;
  210.         $z = $v[$n];
  211.         $y = $v[0];
  212.         $q = floor(6 + 52 / ($n + 1));
  213.         $sum = 0;
  214.         while (0 < $q--) {
  215.             $sum = $this->_int32($sum + CRYPT_XXTEA_DELTA);
  216.             $e = $sum >> 2 & 3;
  217.             for ($p = 0; $p < $n; $p++) {
  218.                 $y = $v[$p + 1];
  219.                 $mx = $this->_int32((($z >> 5 & 0x07FFFFFF) ^ $y << 2) + (($y >> 3 & 0x1FFFFFFF) ^ $z << 4)) ^ $this->_int32(($sum ^ $y) + ($this->_key[$p & 3 ^ $e] ^ $z));
  220.                 $z = $v[$p] = $this->_int32($v[$p] + $mx);
  221.             }
  222.             $y = $v[0];
  223.             $mx = $this->_int32((($z >> 5 & 0x07FFFFFF) ^ $y << 2) + (($y >> 3 & 0x1FFFFFFF) ^ $z << 4)) ^ $this->_int32(($sum ^ $y) + ($this->_key[$p & 3 ^ $e] ^ $z));
  224.             $z = $v[$n] = $this->_int32($v[$n] + $mx);
  225.         }
  226.         return $v;
  227.     }
  228.  
  229.     // }}}
  230.  
  231.     // {{{ _decryptString()
  232.  
  233.     /**
  234.      * Decrypts a string
  235.      *
  236.      * @access private
  237.      *
  238.      * @param string $str  the string to decrypt
  239.      *
  240.      * @return string  the string type of the plain text on success,
  241.      *                 PEAR_Error on failure
  242.      */
  243.     function _decryptString($str) {
  244.         if ($str == '') {
  245.             return '';
  246.         }
  247.         $v = $this->_str2long($str, false);
  248.         $v = $this->_decryptArray($v);
  249.         return $this->_long2str($v, true);
  250.     }
  251.  
  252.     // }}}
  253.  
  254.     // {{{ _encryptArray()
  255.  
  256.     /**
  257.      * Decrypts a long integer array
  258.      *
  259.      * @access private
  260.      *
  261.      * @param array $v  the long integer array to decrypt
  262.      *
  263.      * @return array  the array type of the plain text on success,
  264.      *                PEAR_Error on failure
  265.      */
  266.     function _decryptArray($v) {
  267.         $n = count($v) - 1;
  268.         $z = $v[$n];
  269.         $y = $v[0];
  270.         $q = floor(6 + 52 / ($n + 1));
  271.         $sum = $this->_int32($q * CRYPT_XXTEA_DELTA);
  272.         while ($sum != 0) {
  273.             $e = $sum >> 2 & 3;
  274.             for ($p = $n; $p > 0; $p--) {
  275.                 $z = $v[$p - 1];
  276.                 $mx = $this->_int32((($z >> 5 & 0x07FFFFFF) ^ $y << 2) + (($y >> 3 & 0x1FFFFFFF) ^ $z << 4)) ^ $this->_int32(($sum ^ $y) + ($this->_key[$p & 3 ^ $e] ^ $z));
  277.                 $y = $v[$p] = $this->_int32($v[$p] - $mx);
  278.             }
  279.             $z = $v[$n];
  280.             $mx = $this->_int32((($z >> 5 & 0x07FFFFFF) ^ $y << 2) + (($y >> 3 & 0x1FFFFFFF) ^ $z << 4)) ^ $this->_int32(($sum ^ $y) + ($this->_key[$p & 3 ^ $e] ^ $z));
  281.             $y = $v[0] = $this->_int32($v[0] - $mx);
  282.             $sum = $this->_int32($sum - CRYPT_XXTEA_DELTA);
  283.         }
  284.         return $v;
  285.     }
  286.  
  287.     // }}}
  288.  
  289.     // {{{ _long2str()
  290.  
  291.     /**
  292.      * Converts long integer array to string
  293.      *
  294.      * @access private
  295.      *
  296.      * @param array $v  the long integer array
  297.      * @param bool  $w  whether the given array contains the length of
  298.      *                  original plain text
  299.      *
  300.      * @return string  the string
  301.      */
  302.     function _long2str($v, $w) {
  303.         $len = count($v);
  304.         $s = '';
  305.         for ($i = 0; $i < $len; $i++) {
  306.             $s .= pack('V', $v[$i]);
  307.         }
  308.         if ($w) {
  309.             return substr($s, 0, $v[$len - 1]);
  310.         } else {
  311.             return $s;
  312.         }
  313.     }
  314.  
  315.     // }}}
  316.  
  317.     // {{{ _str2long()
  318.  
  319.     /**
  320.      * Converts string to long integer array
  321.      *
  322.      * @access private
  323.      *
  324.      * @param string $s  the string
  325.      * @param bool   $w  whether to append the length of string to array
  326.      *
  327.      * @return string  the long integer array
  328.      */
  329.     function _str2long($s, $w) {
  330.         $v = array_values(unpack('V*', $s.str_repeat("\0", (4-strlen($s)%4)&3)));
  331.         if ($w) {
  332.             $v[] = strlen($s);
  333.         }
  334.         return $v;
  335.     }
  336.  
  337.     // }}}
  338.  
  339.     // {{{ _int32()
  340.  
  341.     /**
  342.      * Corrects long integer value
  343.      *
  344.      * Because a number beyond the bounds of the integer type will be automatically
  345.      * interpreted as a float, the simulation of integer overflow is needed.
  346.      *
  347.      * @access private
  348.      *
  349.      * @param int $n  the integer
  350.      *
  351.      * @return int  the correct integer
  352.      */
  353.     function _int32($n) {
  354.         while ($n >= 2147483648) $n -= 4294967296;
  355.         while ($n <= -2147483649) $n += 4294967296;
  356.         return (int)$n;
  357.     }
  358.  
  359.     // }}}
  360.  
  361. }
  362.  
  363. ?>
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement