std.encryption.class.inc 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279
  1. <?php
  2. // ******************************************************************************
  3. // A reversible password encryption routine by:
  4. // Copyright 2003-2009 by A J Marston <http://www.tonymarston.net>
  5. // Distributed under the GNU General Public Licence
  6. // Modification: May 2007, M. Kolar <http://mkolar.org>:
  7. // No need for repeating the first character of scramble strings at the end;
  8. // instead using the exact inverse function transforming $num2 to $num1.
  9. // Modification: Jan 2009, A J Marston <http://www.tonymarston.net>:
  10. // Use mb_substr() if it is available (for multibyte characters).
  11. // ******************************************************************************
  12. class encryption_class {
  13. var $scramble1; // 1st string of ASCII characters
  14. var $scramble2; // 2nd string of ASCII characters
  15. var $errors; // array of error messages
  16. var $adj; // 1st adjustment value (optional)
  17. var $mod; // 2nd adjustment value (optional)
  18. // ****************************************************************************
  19. // class constructor
  20. // ****************************************************************************
  21. function encryption_class ()
  22. {
  23. $this->errors = array();
  24. // Each of these two strings must contain the same characters, but in a different order.
  25. // Use only printable characters from the ASCII table.
  26. // Do not use single quote, double quote or backslash as these have special meanings in PHP.
  27. // Each character can only appear once in each string.
  28. $this->scramble1 = '! #$%&()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~';
  29. $this->scramble2 = 'f^jAE]okIOzU[2&q1{3`h5w_794p@6s8?BgP>dFV=m D<TcS%Ze|r:lGK/uCy.Jx)HiQ!#$~(;Lt-R}Ma,NvW+Ynb*0X';
  30. if (strlen($this->scramble1) <> strlen($this->scramble2)) {
  31. trigger_error('** SCRAMBLE1 is not same length as SCRAMBLE2 **', E_USER_ERROR);
  32. } // if
  33. $this->adj = 1.75; // this value is added to the rolling fudgefactors
  34. $this->mod = 3; // if divisible by this the adjustment is made negative
  35. } // constructor
  36. // ****************************************************************************
  37. function decrypt ($key, $source)
  38. // decrypt string into its original form
  39. {
  40. $this->errors = array();
  41. // convert $key into a sequence of numbers
  42. $fudgefactor = $this->_convertKey($key);
  43. if ($this->errors) return;
  44. if (empty($source)) {
  45. $this->errors[] = 'No value has been supplied for decryption';
  46. return;
  47. } // if
  48. $target = null;
  49. $factor2 = 0;
  50. for ($i = 0; $i < strlen($source); $i++) {
  51. // extract a (multibyte) character from $source
  52. if (function_exists('mb_substr')) {
  53. $char2 = mb_substr($source, $i, 1);
  54. } else {
  55. $char2 = substr($source, $i, 1);
  56. } // if
  57. // identify its position in $scramble2
  58. $num2 = strpos($this->scramble2, $char2);
  59. if ($num2 === false) {
  60. $this->errors[] = "Source string contains an invalid character ($char2)";
  61. return;
  62. } // if
  63. // get an adjustment value using $fudgefactor
  64. $adj = $this->_applyFudgeFactor($fudgefactor);
  65. $factor1 = $factor2 + $adj; // accumulate in $factor1
  66. $num1 = $num2 - round($factor1); // generate offset for $scramble1
  67. $num1 = $this->_checkRange($num1); // check range
  68. $factor2 = $factor1 + $num2; // accumulate in $factor2
  69. // extract (multibyte) character from $scramble1
  70. if (function_exists('mb_substr')) {
  71. $char1 = mb_substr($this->scramble1, $num1, 1);
  72. } else {
  73. $char1 = substr($this->scramble1, $num1, 1);
  74. } // if
  75. // append to $target string
  76. $target .= $char1;
  77. //echo "char1=$char1, num1=$num1, adj= $adj, factor1= $factor1, num2=$num2, char2=$char2, factor2= $factor2<br />\n";
  78. } // for
  79. return rtrim($target);
  80. } // decrypt
  81. // ****************************************************************************
  82. function encrypt ($key, $source, $sourcelen = 0)
  83. // encrypt string into a garbled form
  84. {
  85. $this->errors = array();
  86. // convert $key into a sequence of numbers
  87. $fudgefactor = $this->_convertKey($key);
  88. if ($this->errors) return;
  89. if (empty($source)) {
  90. $this->errors[] = 'No value has been supplied for encryption';
  91. return;
  92. } // if
  93. // pad $source with spaces up to $sourcelen
  94. $source = str_pad($source, $sourcelen);
  95. $target = null;
  96. $factor2 = 0;
  97. for ($i = 0; $i < strlen($source); $i++) {
  98. // extract a (multibyte) character from $source
  99. if (function_exists('mb_substr')) {
  100. $char1 = mb_substr($source, $i, 1);
  101. } else {
  102. $char1 = substr($source, $i, 1);
  103. } // if
  104. // identify its position in $scramble1
  105. $num1 = strpos($this->scramble1, $char1);
  106. if ($num1 === false) {
  107. $this->errors[] = "Source string contains an invalid character ($char1)";
  108. return;
  109. } // if
  110. // get an adjustment value using $fudgefactor
  111. $adj = $this->_applyFudgeFactor($fudgefactor);
  112. $factor1 = $factor2 + $adj; // accumulate in $factor1
  113. $num2 = round($factor1) + $num1; // generate offset for $scramble2
  114. $num2 = $this->_checkRange($num2); // check range
  115. $factor2 = $factor1 + $num2; // accumulate in $factor2
  116. // extract (multibyte) character from $scramble2
  117. if (function_exists('mb_substr')) {
  118. $char2 = mb_substr($this->scramble2, $num2, 1);
  119. } else {
  120. $char2 = substr($this->scramble2, $num2, 1);
  121. } // if
  122. // append to $target string
  123. $target .= $char2;
  124. //echo "char1=$char1, num1=$num1, adj= $adj, factor1= $factor1, num2=$num2, char2=$char2, factor2= $factor2<br />\n";
  125. } // for
  126. return $target;
  127. } // encrypt
  128. // ****************************************************************************
  129. function getAdjustment ()
  130. // return the adjustment value
  131. {
  132. return $this->adj;
  133. } // setAdjustment
  134. // ****************************************************************************
  135. function getModulus ()
  136. // return the modulus value
  137. {
  138. return $this->mod;
  139. } // setModulus
  140. // ****************************************************************************
  141. function setAdjustment ($adj)
  142. // set the adjustment value
  143. {
  144. $this->adj = (float)$adj;
  145. } // setAdjustment
  146. // ****************************************************************************
  147. function setModulus ($mod)
  148. // set the modulus value
  149. {
  150. $this->mod = (int)abs($mod); // must be a positive whole number
  151. } // setModulus
  152. // ****************************************************************************
  153. // private methods
  154. // ****************************************************************************
  155. function _applyFudgeFactor (&$fudgefactor)
  156. // return an adjustment value based on the contents of $fudgefactor
  157. // NOTE: $fudgefactor is passed by reference so that it can be modified
  158. {
  159. $fudge = array_shift($fudgefactor); // extract 1st number from array
  160. $fudge = $fudge + $this->adj; // add in adjustment value
  161. $fudgefactor[] = $fudge; // put it back at end of array
  162. if (!empty($this->mod)) { // if modifier has been supplied
  163. if ($fudge % $this->mod == 0) { // if it is divisible by modifier
  164. $fudge = $fudge * -1; // make it negative
  165. } // if
  166. } // if
  167. return $fudge;
  168. } // _applyFudgeFactor
  169. // ****************************************************************************
  170. function _checkRange ($num)
  171. // check that $num points to an entry in $this->scramble1
  172. {
  173. $num = round($num); // round up to nearest whole number
  174. $limit = strlen($this->scramble1);
  175. while ($num >= $limit) {
  176. $num = $num - $limit; // value too high, so reduce it
  177. } // while
  178. while ($num < 0) {
  179. $num = $num + $limit; // value too low, so increase it
  180. } // while
  181. return $num;
  182. } // _checkRange
  183. // ****************************************************************************
  184. function _convertKey ($key)
  185. // convert $key into an array of numbers
  186. {
  187. if (empty($key)) {
  188. $this->errors[] = 'No value has been supplied for the encryption key';
  189. return;
  190. } // if
  191. $array[] = strlen($key); // first entry in array is length of $key
  192. $tot = 0;
  193. for ($i = 0; $i < strlen($key); $i++) {
  194. // extract a (multibyte) character from $key
  195. if (function_exists('mb_substr')) {
  196. $char = mb_substr($key, $i, 1);
  197. } else {
  198. $char = substr($key, $i, 1);
  199. } // if
  200. // identify its position in $scramble1
  201. $num = strpos($this->scramble1, $char);
  202. if ($num === false) {
  203. $this->errors[] = "Key contains an invalid character ($char)";
  204. return;
  205. } // if
  206. $array[] = $num; // store in output array
  207. $tot = $tot + $num; // accumulate total for later
  208. } // for
  209. $array[] = $tot; // insert total as last entry in array
  210. return $array;
  211. } // _convertKey
  212. // ****************************************************************************
  213. } // end encryption_class
  214. // ****************************************************************************
  215. ?>