~jstys-z/helioviewer.org/client5

« back to all changes in this revision

Viewing changes to api/lib/alphaID/alphaID.php

  • Committer: Keith Hughitt
  • Date: 2012-08-10 18:15:41 UTC
  • mfrom: (402.4.61 hv)
  • Revision ID: keith.hughitt@nasa.gov-20120810181541-4zkdf7td1igj55lw
Merged in development changes

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
<?php
 
2
/**
 
3
 * Translates a number to a short alhanumeric version
 
4
 *
 
5
 * Translated any number up to 9007199254740992
 
6
 * to a shorter version in letters e.g.:
 
7
 * 9007199254740989 --> PpQXn7COf
 
8
 *
 
9
 * specifiying the second argument true, it will
 
10
 * translate back e.g.:
 
11
 * PpQXn7COf --> 9007199254740989
 
12
 *
 
13
 * this function is based on any2dec && dec2any by
 
14
 * fragmer[at]mail[dot]ru
 
15
 * see: http://nl3.php.net/manual/en/function.base-convert.php#52450
 
16
 *
 
17
 * If you want the alphaID to be at least 3 letter long, use the
 
18
 * $pad_up = 3 argument
 
19
 *
 
20
 * In most cases this is better than totally random ID generators
 
21
 * because this can easily avoid duplicate ID's.
 
22
 * For example if you correlate the alpha ID to an auto incrementing ID
 
23
 * in your database, you're done.
 
24
 *
 
25
 * The reverse is done because it makes it slightly more cryptic,
 
26
 * but it also makes it easier to spread lots of IDs in different
 
27
 * directories on your filesystem. Example:
 
28
 * $part1 = substr($alpha_id,0,1);
 
29
 * $part2 = substr($alpha_id,1,1);
 
30
 * $part3 = substr($alpha_id,2,strlen($alpha_id));
 
31
 * $destindir = "/".$part1."/".$part2."/".$part3;
 
32
 * // by reversing, directories are more evenly spread out. The
 
33
 * // first 26 directories already occupy 26 main levels
 
34
 *
 
35
 * more info on limitation:
 
36
 * - http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/165372
 
37
 *
 
38
 * if you really need this for bigger numbers you probably have to look
 
39
 * at things like: http://theserverpages.com/php/manual/en/ref.bc.php
 
40
 * or: http://theserverpages.com/php/manual/en/ref.gmp.php
 
41
 * but I haven't really dugg into this. If you have more info on those
 
42
 * matters feel free to leave a comment.
 
43
 *
 
44
 * The following code block can be utilized by PEAR's Testing_DocTest
 
45
 * <code>
 
46
 * // Input //
 
47
 * $number_in = 2188847690240;
 
48
 * $alpha_in  = "SpQXn7Cb";
 
49
 *
 
50
 * // Execute //
 
51
 * $alpha_out  = alphaID($number_in, false, 8);
 
52
 * $number_out = alphaID($alpha_in, true, 8);
 
53
 *
 
54
 * if ($number_in != $number_out) {
 
55
 *       echo "Conversion failure, ".$alpha_in." returns ".$number_out." instead of the ";
 
56
 *       echo "desired: ".$number_in."\n";
 
57
 * }
 
58
 * if ($alpha_in != $alpha_out) {
 
59
 *       echo "Conversion failure, ".$number_in." returns ".$alpha_out." instead of the ";
 
60
 *       echo "desired: ".$alpha_in."\n";
 
61
 * }
 
62
 *
 
63
 * // Show //
 
64
 * echo $number_out." => ".$alpha_out."\n";
 
65
 * echo $alpha_in." => ".$number_out."\n";
 
66
 * echo alphaID(238328, false)." => ".alphaID(alphaID(238328, false), true)."\n";
 
67
 *
 
68
 * // expects:
 
69
 * // 2188847690240 => SpQXn7Cb
 
70
 * // SpQXn7Cb => 2188847690240
 
71
 * // aaab => 238328
 
72
 *
 
73
 * </code>
 
74
 *
 
75
 * @author      Kevin van Zonneveld <kevin@vanzonneveld.net>
 
76
 * @author      Simon Franz
 
77
 * @author      Deadfish
 
78
 * @copyright 2008 Kevin van Zonneveld (http://kevin.vanzonneveld.net)
 
79
 * @license   http://www.opensource.org/licenses/bsd-license.php New BSD Licence
 
80
 * @version   SVN: Release: $Id: alphaID.inc.php 344 2009-06-10 17:43:59Z kevin $
 
81
 * @link          http://kevin.vanzonneveld.net/
 
82
 *
 
83
 * @param mixed   $in     String or long input to translate
 
84
 * @param boolean $to_num  Reverses translation when true
 
85
 * @param mixed   $pad_up  Number or boolean padds the result up to a specified length
 
86
 * @param string  $passKey Supplying a password makes it harder to calculate the original ID
 
87
 *
 
88
 * @return mixed string or long
 
89
 */
 
90
function alphaID($in, $to_num = false, $pad_up = false, $passKey = null)
 
91
{
 
92
        $index = "bcdfghjklmnpqrstvwxyz0123456789BCDFGHJKLMNPQRSTVWXYZ";
 
93
        if ($passKey !== null) {
 
94
                // Although this function's purpose is to just make the
 
95
                // ID short - and not so much secure,
 
96
                // with this patch by Simon Franz (http://blog.snaky.org/)
 
97
                // you can optionally supply a password to make it harder
 
98
                // to calculate the corresponding numeric ID
 
99
 
 
100
                for ($n = 0; $n<strlen($index); $n++) {
 
101
                        $i[] = substr( $index,$n ,1);
 
102
                }
 
103
 
 
104
                $passhash = hash('sha256',$passKey);
 
105
                $passhash = (strlen($passhash) < strlen($index))
 
106
                        ? hash('sha512',$passKey)
 
107
                        : $passhash;
 
108
 
 
109
                for ($n=0; $n < strlen($index); $n++) {
 
110
                        $p[] =  substr($passhash, $n ,1);
 
111
                }
 
112
 
 
113
                array_multisort($p,  SORT_DESC, $i);
 
114
                $index = implode($i);
 
115
        }
 
116
 
 
117
        $base  = strlen($index);
 
118
 
 
119
        if ($to_num) {
 
120
                // Digital number  <<--  alphabet letter code
 
121
                $in  = strrev($in);
 
122
                $out = 0;
 
123
                $len = strlen($in) - 1;
 
124
                for ($t = 0; $t <= $len; $t++) {
 
125
                        $bcpow = bcpow($base, $len - $t);
 
126
                        $out   = $out + strpos($index, substr($in, $t, 1)) * $bcpow;
 
127
                }
 
128
 
 
129
                if (is_numeric($pad_up)) {
 
130
                        $pad_up--;
 
131
                        if ($pad_up > 0) {
 
132
                                $out -= pow($base, $pad_up);
 
133
                        }
 
134
                }
 
135
                $out = sprintf('%F', $out);
 
136
                $out = substr($out, 0, strpos($out, '.'));
 
137
        } else {
 
138
                // Digital number  -->>  alphabet letter code
 
139
                if (is_numeric($pad_up)) {
 
140
                        $pad_up--;
 
141
                        if ($pad_up > 0) {
 
142
                                $in += pow($base, $pad_up);
 
143
                        }
 
144
                }
 
145
 
 
146
                $out = "";
 
147
                for ($t = floor(log($in, $base)); $t >= 0; $t--) {
 
148
                        $bcp = bcpow($base, $t);
 
149
                        $a   = floor($in / $bcp) % $base;
 
150
                        $out = $out . substr($index, $a, 1);
 
151
                        $in  = $in - ($a * $bcp);
 
152
                }
 
153
                $out = strrev($out); // reverse
 
154
        }
 
155
 
 
156
        return $out;
 
157
}