Gentics Portal.Node PHP API
 All Classes Namespaces Functions Variables Pages
encryption_class.php
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 
14 
15  var $scramble1; // 1st string of ASCII characters
16  var $scramble2; // 2nd string of ASCII characters
17 
18  var $errors; // array of error messages
19  var $adj; // 1st adjustment value (optional)
20  var $mod; // 2nd adjustment value (optional)
21 
22  // ****************************************************************************
23  // class constructor
24  // ****************************************************************************
25  function encryption_class ()
26  {
27  $this->errors = array();
28 
29  // Each of these two strings must contain the same characters, but in a different order.
30  // Use only printable characters from the ASCII table.
31  // Do not use single quote, double quote or backslash as these have special meanings in PHP.
32  // Each character can only appear once in each string.
33  $this->scramble1 = '! #$%&()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~';
34  $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';
35 
36  if (strlen($this->scramble1) <> strlen($this->scramble2)) {
37  trigger_error('** SCRAMBLE1 is not same length as SCRAMBLE2 **', E_USER_ERROR);
38  } // if
39 
40  $this->adj = 1.75; // this value is added to the rolling fudgefactors
41  $this->mod = 3; // if divisible by this the adjustment is made negative
42 
43  } // constructor
44 
45  // ****************************************************************************
46  function decrypt ($key, $source)
47  // decrypt string into its original form
48  {
49  $this->errors = array();
50 
51  // convert $key into a sequence of numbers
52  $fudgefactor = $this->_convertKey($key);
53  if ($this->errors) return;
54 
55  if (empty($source)) {
56  $this->errors[] = 'No value has been supplied for decryption';
57  return;
58  } // if
59 
60  $target = null;
61  $factor2 = 0;
62 
63  for ($i = 0; $i < strlen($source); $i++) {
64  // extract a (multibyte) character from $source
65  if (function_exists('mb_substr')) {
66  $char2 = mb_substr($source, $i, 1);
67  } else {
68  $char2 = substr($source, $i, 1);
69  } // if
70 
71  // identify its position in $scramble2
72  $num2 = strpos($this->scramble2, $char2);
73  if ($num2 === false) {
74  $this->errors[] = "Source string contains an invalid character ($char2)";
75  return;
76  } // if
77 
78  // get an adjustment value using $fudgefactor
79  $adj = $this->_applyFudgeFactor($fudgefactor);
80 
81  $factor1 = $factor2 + $adj; // accumulate in $factor1
82  $num1 = $num2 - round($factor1); // generate offset for $scramble1
83  $num1 = $this->_checkRange($num1); // check range
84  $factor2 = $factor1 + $num2; // accumulate in $factor2
85 
86  // extract (multibyte) character from $scramble1
87  if (function_exists('mb_substr')) {
88  $char1 = mb_substr($this->scramble1, $num1, 1);
89  } else {
90  $char1 = substr($this->scramble1, $num1, 1);
91  } // if
92 
93  // append to $target string
94  $target .= $char1;
95 
96  //echo "char1=$char1, num1=$num1, adj= $adj, factor1= $factor1, num2=$num2, char2=$char2, factor2= $factor2<br />\n";
97 
98  } // for
99 
100  return rtrim($target);
101 
102  } // decrypt
103 
104  // ****************************************************************************
105  function encrypt ($key, $source, $sourcelen = 0)
106  // encrypt string into a garbled form
107  {
108  $this->errors = array();
109 
110  // convert $key into a sequence of numbers
111  $fudgefactor = $this->_convertKey($key);
112  if ($this->errors) return;
113 
114  if (empty($source)) {
115  $this->errors[] = 'No value has been supplied for encryption';
116  return;
117  } // if
118 
119  // pad $source with spaces up to $sourcelen
120  $source = str_pad($source, $sourcelen);
121 
122  $target = null;
123  $factor2 = 0;
124 
125  for ($i = 0; $i < strlen($source); $i++) {
126  // extract a (multibyte) character from $source
127  if (function_exists('mb_substr')) {
128  $char1 = mb_substr($source, $i, 1);
129  } else {
130  $char1 = substr($source, $i, 1);
131  } // if
132 
133  // identify its position in $scramble1
134  $num1 = strpos($this->scramble1, $char1);
135  if ($num1 === false) {
136  $this->errors[] = "Source string contains an invalid character ($char1)";
137  return;
138  } // if
139 
140  // get an adjustment value using $fudgefactor
141  $adj = $this->_applyFudgeFactor($fudgefactor);
142 
143  $factor1 = $factor2 + $adj; // accumulate in $factor1
144  $num2 = round($factor1) + $num1; // generate offset for $scramble2
145  $num2 = $this->_checkRange($num2); // check range
146  $factor2 = $factor1 + $num2; // accumulate in $factor2
147 
148  // extract (multibyte) character from $scramble2
149  if (function_exists('mb_substr')) {
150  $char2 = mb_substr($this->scramble2, $num2, 1);
151  } else {
152  $char2 = substr($this->scramble2, $num2, 1);
153  } // if
154 
155  // append to $target string
156  $target .= $char2;
157 
158  //echo "char1=$char1, num1=$num1, adj= $adj, factor1= $factor1, num2=$num2, char2=$char2, factor2= $factor2<br />\n";
159 
160  } // for
161 
162  return $target;
163 
164  } // encrypt
165 
166  // ****************************************************************************
167  function getAdjustment ()
168  // return the adjustment value
169  {
170  return $this->adj;
171 
172  } // setAdjustment
173 
174  // ****************************************************************************
175  function getModulus ()
176  // return the modulus value
177  {
178  return $this->mod;
179 
180  } // setModulus
181 
182  // ****************************************************************************
183  function setAdjustment ($adj)
184  // set the adjustment value
185  {
186  $this->adj = (float)$adj;
187 
188  } // setAdjustment
189 
190  // ****************************************************************************
191  function setModulus ($mod)
192  // set the modulus value
193  {
194  $this->mod = (int)abs($mod); // must be a positive whole number
195 
196  } // setModulus
197 
198  // ****************************************************************************
199  // private methods
200  // ****************************************************************************
201  function _applyFudgeFactor (&$fudgefactor)
202  // return an adjustment value based on the contents of $fudgefactor
203  // NOTE: $fudgefactor is passed by reference so that it can be modified
204  {
205  $fudge = array_shift($fudgefactor); // extract 1st number from array
206  $fudge = $fudge + $this->adj; // add in adjustment value
207  $fudgefactor[] = $fudge; // put it back at end of array
208 
209  if (!empty($this->mod)) { // if modifier has been supplied
210  if ($fudge % $this->mod == 0) { // if it is divisible by modifier
211  $fudge = $fudge * -1; // make it negative
212  } // if
213  } // if
214 
215  return $fudge;
216 
217  } // _applyFudgeFactor
218 
219  // ****************************************************************************
220  function _checkRange ($num)
221  // check that $num points to an entry in $this->scramble1
222  {
223  $num = round($num); // round up to nearest whole number
224 
225  $limit = strlen($this->scramble1);
226 
227  while ($num >= $limit) {
228  $num = $num - $limit; // value too high, so reduce it
229  } // while
230  while ($num < 0) {
231  $num = $num + $limit; // value too low, so increase it
232  } // while
233 
234  return $num;
235 
236  } // _checkRange
237 
238  // ****************************************************************************
239  function _convertKey ($key)
240  // convert $key into an array of numbers
241  {
242  if (empty($key)) {
243  $this->errors[] = 'No value has been supplied for the encryption key';
244  return;
245  } // if
246 
247  $array[] = strlen($key); // first entry in array is length of $key
248 
249  $tot = 0;
250  for ($i = 0; $i < strlen($key); $i++) {
251  // extract a (multibyte) character from $key
252  if (function_exists('mb_substr')) {
253  $char = mb_substr($key, $i, 1);
254  } else {
255  $char = substr($key, $i, 1);
256  } // if
257 
258  // identify its position in $scramble1
259  $num = strpos($this->scramble1, $char);
260  if ($num === false) {
261  $this->errors[] = "Key contains an invalid character ($char)";
262  return;
263  } // if
264 
265  $array[] = $num; // store in output array
266  $tot = $tot + $num; // accumulate total for later
267  } // for
268 
269  $array[] = $tot; // insert total as last entry in array
270 
271  return $array;
272 
273  } // _convertKey
274 
275 // ****************************************************************************
276 } // end encryption_class
277 // ****************************************************************************
278 
279 ?>