Encryption.php 10 KB

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