diff options
Diffstat (limited to 'inc/3rdparty/libraries/PHPePub/lib.uuid.php')
-rw-r--r-- | inc/3rdparty/libraries/PHPePub/lib.uuid.php | 314 |
1 files changed, 314 insertions, 0 deletions
diff --git a/inc/3rdparty/libraries/PHPePub/lib.uuid.php b/inc/3rdparty/libraries/PHPePub/lib.uuid.php new file mode 100644 index 00000000..c6a8de52 --- /dev/null +++ b/inc/3rdparty/libraries/PHPePub/lib.uuid.php | |||
@@ -0,0 +1,314 @@ | |||
1 | <?php | ||
2 | /* | ||
3 | DrUUID RFC4122 library for PHP5 | ||
4 | by J. King (http://jkingweb.ca/) | ||
5 | Licensed under MIT license | ||
6 | |||
7 | See http://jkingweb.ca/code/php/lib.uuid/ | ||
8 | for documentation | ||
9 | |||
10 | Last revised 2010-02-15 | ||
11 | */ | ||
12 | |||
13 | /* | ||
14 | Copyright (c) 2009 J. King | ||
15 | |||
16 | Permission is hereby granted, free of charge, to any person | ||
17 | obtaining a copy of this software and associated documentation | ||
18 | files (the "Software"), to deal in the Software without | ||
19 | restriction, including without limitation the rights to use, | ||
20 | copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
21 | copies of the Software, and to permit persons to whom the | ||
22 | Software is furnished to do so, subject to the following | ||
23 | conditions: | ||
24 | |||
25 | The above copyright notice and this permission notice shall be | ||
26 | included in all copies or substantial portions of the Software. | ||
27 | |||
28 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
29 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES | ||
30 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
31 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT | ||
32 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, | ||
33 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | ||
34 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | ||
35 | OTHER DEALINGS IN THE SOFTWARE. | ||
36 | */ | ||
37 | |||
38 | |||
39 | class UUID { | ||
40 | const MD5 = 3; | ||
41 | const SHA1 = 5; | ||
42 | const clearVer = 15; // 00001111 Clears all bits of version byte with AND | ||
43 | const clearVar = 63; // 00111111 Clears all relevant bits of variant byte with AND | ||
44 | const varRes = 224; // 11100000 Variant reserved for future use | ||
45 | const varMS = 192; // 11000000 Microsft GUID variant | ||
46 | const varRFC = 128; // 10000000 The RFC 4122 variant (this variant) | ||
47 | const varNCS = 0; // 00000000 The NCS compatibility variant | ||
48 | const version1 = 16; // 00010000 | ||
49 | const version3 = 48; // 00110000 | ||
50 | const version4 = 64; // 01000000 | ||
51 | const version5 = 80; // 01010000 | ||
52 | const interval = 0x01b21dd213814000; // Time (in 100ns steps) between the start of the UTC and Unix epochs | ||
53 | const nsDNS = '6ba7b810-9dad-11d1-80b4-00c04fd430c8'; | ||
54 | const nsURL = '6ba7b811-9dad-11d1-80b4-00c04fd430c8'; | ||
55 | const nsOID = '6ba7b812-9dad-11d1-80b4-00c04fd430c8'; | ||
56 | const nsX500 = '6ba7b814-9dad-11d1-80b4-00c04fd430c8'; | ||
57 | protected static $randomFunc = 'randomTwister'; | ||
58 | protected static $randomSource = NULL; | ||
59 | //instance properties | ||
60 | protected $bytes; | ||
61 | protected $hex; | ||
62 | protected $string; | ||
63 | protected $urn; | ||
64 | protected $version; | ||
65 | protected $variant; | ||
66 | protected $node; | ||
67 | protected $time; | ||
68 | |||
69 | public static function mint($ver = 1, $node = NULL, $ns = NULL) { | ||
70 | /* Create a new UUID based on provided data. */ | ||
71 | switch((int) $ver) { | ||
72 | case 1: | ||
73 | return new self(self::mintTime($node)); | ||
74 | case 2: | ||
75 | // Version 2 is not supported | ||
76 | throw new UUIDException("Version 2 is unsupported."); | ||
77 | case 3: | ||
78 | return new self(self::mintName(self::MD5, $node, $ns)); | ||
79 | case 4: | ||
80 | return new self(self::mintRand()); | ||
81 | case 5: | ||
82 | return new self(self::mintName(self::SHA1, $node, $ns)); | ||
83 | default: | ||
84 | throw new UUIDException("Selected version is invalid or unsupported."); | ||
85 | } | ||
86 | } | ||
87 | |||
88 | public static function import($uuid) { | ||
89 | /* Import an existing UUID. */ | ||
90 | return new self(self::makeBin($uuid, 16)); | ||
91 | } | ||
92 | |||
93 | public static function compare($a, $b) { | ||
94 | /* Compares the binary representations of two UUIDs. | ||
95 | The comparison will return true if they are bit-exact, | ||
96 | or if neither is valid. */ | ||
97 | if (self::makeBin($a, 16)==self::makeBin($b, 16)) { | ||
98 | return TRUE; | ||
99 | } else { | ||
100 | return FALSE; | ||
101 | } | ||
102 | } | ||
103 | |||
104 | public function __toString() { | ||
105 | return $this->string; | ||
106 | } | ||
107 | |||
108 | public function __get($var) { | ||
109 | switch($var) { | ||
110 | case "bytes": | ||
111 | return $this->bytes; | ||
112 | case "hex": | ||
113 | return bin2hex($this->bytes); | ||
114 | case "string": | ||
115 | return $this->__toString(); | ||
116 | case "urn": | ||
117 | return "urn:uuid:".$this->__toString(); | ||
118 | case "version": | ||
119 | return ord($this->bytes[6]) >> 4; | ||
120 | case "variant": | ||
121 | $byte = ord($this->bytes[8]); | ||
122 | if ($byte >= self::varRes) { | ||
123 | return 3; | ||
124 | } | ||
125 | if ($byte >= self::varMS) { | ||
126 | return 2; | ||
127 | } | ||
128 | if ($byte >= self::varRFC) { | ||
129 | return 1; | ||
130 | } | ||
131 | return 0; | ||
132 | case "node": | ||
133 | if (ord($this->bytes[6])>>4==1) { | ||
134 | return bin2hex(substr($this->bytes,10)); | ||
135 | } else { | ||
136 | return NULL; | ||
137 | } | ||
138 | case "time": | ||
139 | if (ord($this->bytes[6])>>4==1) { | ||
140 | // Restore contiguous big-endian byte order | ||
141 | $time = bin2hex($this->bytes[6].$this->bytes[7].$this->bytes[4].$this->bytes[5].$this->bytes[0].$this->bytes[1].$this->bytes[2].$this->bytes[3]); | ||
142 | // Clear version flag | ||
143 | $time[0] = "0"; | ||
144 | // Do some reverse arithmetic to get a Unix timestamp | ||
145 | $time = (hexdec($time) - self::interval) / 10000000; | ||
146 | return $time; | ||
147 | } else { | ||
148 | return NULL; | ||
149 | } | ||
150 | default: | ||
151 | return NULL; | ||
152 | } | ||
153 | } | ||
154 | |||
155 | protected function __construct($uuid) { | ||
156 | if (strlen($uuid) != 16) { | ||
157 | throw new UUIDException("Input must be a 128-bit integer."); | ||
158 | } | ||
159 | $this->bytes = $uuid; | ||
160 | // Optimize the most common use | ||
161 | $this->string = | ||
162 | bin2hex(substr($uuid,0,4))."-". | ||
163 | bin2hex(substr($uuid,4,2))."-". | ||
164 | bin2hex(substr($uuid,6,2))."-". | ||
165 | bin2hex(substr($uuid,8,2))."-". | ||
166 | bin2hex(substr($uuid,10,6)); | ||
167 | } | ||
168 | |||
169 | protected static function mintTime($node = NULL) { | ||
170 | /* Generates a Version 1 UUID. | ||
171 | These are derived from the time at which they were generated. */ | ||
172 | // Get time since Gregorian calendar reform in 100ns intervals | ||
173 | // This is exceedingly difficult because of PHP's (and pack()'s) | ||
174 | // integer size limits. | ||
175 | // Note that this will never be more accurate than to the microsecond. | ||
176 | $time = microtime(1) * 10000000 + self::interval; | ||
177 | // Convert to a string representation | ||
178 | $time = sprintf("%F", $time); | ||
179 | preg_match("/^\d+/", $time, $time); //strip decimal point | ||
180 | // And now to a 64-bit binary representation | ||
181 | $time = base_convert($time[0], 10, 16); | ||
182 | $time = pack("H*", str_pad($time, 16, "0", STR_PAD_LEFT)); | ||
183 | // Reorder bytes to their proper locations in the UUID | ||
184 | $uuid = $time[4].$time[5].$time[6].$time[7].$time[2].$time[3].$time[0].$time[1]; | ||
185 | // Generate a random clock sequence | ||
186 | $uuid .= self::randomBytes(2); | ||
187 | // set variant | ||
188 | $uuid[8] = chr(ord($uuid[8]) & self::clearVar | self::varRFC); | ||
189 | // set version | ||
190 | $uuid[6] = chr(ord($uuid[6]) & self::clearVer | self::version1); | ||
191 | // Set the final 'node' parameter, a MAC address | ||
192 | if ($node) { | ||
193 | $node = self::makeBin($node, 6); | ||
194 | } | ||
195 | if (!$node) { | ||
196 | // If no node was provided or if the node was invalid, | ||
197 | // generate a random MAC address and set the multicast bit | ||
198 | $node = self::randomBytes(6); | ||
199 | $node[0] = pack("C", ord($node[0]) | 1); | ||
200 | } | ||
201 | $uuid .= $node; | ||
202 | return $uuid; | ||
203 | } | ||
204 | |||
205 | protected static function mintRand() { | ||
206 | /* Generate a Version 4 UUID. | ||
207 | These are derived soly from random numbers. */ | ||
208 | // generate random fields | ||
209 | $uuid = self::randomBytes(16); | ||
210 | // set variant | ||
211 | $uuid[8] = chr(ord($uuid[8]) & self::clearVar | self::varRFC); | ||
212 | // set version | ||
213 | $uuid[6] = chr(ord($uuid[6]) & self::clearVer | self::version4); | ||
214 | return $uuid; | ||
215 | } | ||
216 | |||
217 | protected static function mintName($ver, $node, $ns) { | ||
218 | /* Generates a Version 3 or Version 5 UUID. | ||
219 | These are derived from a hash of a name and its namespace, in binary form. */ | ||
220 | if (!$node) { | ||
221 | throw new UUIDException("A name-string is required for Version 3 or 5 UUIDs."); | ||
222 | } | ||
223 | // if the namespace UUID isn't binary, make it so | ||
224 | $ns = self::makeBin($ns, 16); | ||
225 | if (!$ns) { | ||
226 | throw new UUIDException("A binary namespace is required for Version 3 or 5 UUIDs."); | ||
227 | } | ||
228 | $uuid = null; | ||
229 | $version = self::version3; | ||
230 | switch($ver) { | ||
231 | case self::MD5: | ||
232 | $version = self::version3; | ||
233 | $uuid = md5($ns.$node,1); | ||
234 | break; | ||
235 | case self::SHA1: | ||
236 | $version = self::version5; | ||
237 | $uuid = substr(sha1($ns.$node,1),0, 16); | ||
238 | break; | ||
239 | } | ||
240 | // set variant | ||
241 | $uuid[8] = chr(ord($uuid[8]) & self::clearVar | self::varRFC); | ||
242 | // set version | ||
243 | $uuid[6] = chr(ord($uuid[6]) & self::clearVer | $version); | ||
244 | return ($uuid); | ||
245 | } | ||
246 | |||
247 | protected static function makeBin($str, $len) { | ||
248 | /* Insure that an input string is either binary or hexadecimal. | ||
249 | Returns binary representation, or false on failure. */ | ||
250 | if ($str instanceof self) { | ||
251 | return $str->bytes; | ||
252 | } | ||
253 | if (strlen($str)==$len) { | ||
254 | return $str; | ||
255 | } else { | ||
256 | $str = preg_replace("/^urn:uuid:/is", "", $str); // strip URN scheme and namespace | ||
257 | } | ||
258 | $str = preg_replace("/[^a-f0-9]/is", "", $str); // strip non-hex characters | ||
259 | if (strlen($str) != ($len * 2)) { | ||
260 | return FALSE; | ||
261 | } else { | ||
262 | return pack("H*", $str); | ||
263 | } | ||
264 | } | ||
265 | |||
266 | public static function initRandom() { | ||
267 | /* Look for a system-provided source of randomness, which is usually crytographically secure. | ||
268 | /dev/urandom is tried first simply out of bias for Linux systems. */ | ||
269 | if (is_readable('/dev/urandom')) { | ||
270 | self::$randomSource = fopen('/dev/urandom', 'rb'); | ||
271 | self::$randomFunc = 'randomFRead'; | ||
272 | } | ||
273 | else if (class_exists('COM', 0)) { | ||
274 | try { | ||
275 | self::$randomSource = new COM('CAPICOM.Utilities.1'); // See http://msdn.microsoft.com/en-us/library/aa388182(VS.85).aspx | ||
276 | self::$randomFunc = 'randomCOM'; | ||
277 | } | ||
278 | catch(Exception $e) { | ||
279 | } | ||
280 | } | ||
281 | return self::$randomFunc; | ||
282 | } | ||
283 | |||
284 | public static function randomBytes($bytes) { | ||
285 | return call_user_func(array('self', self::$randomFunc), $bytes); | ||
286 | } | ||
287 | |||
288 | protected static function randomTwister($bytes) { | ||
289 | /* Get the specified number of random bytes, using mt_rand(). | ||
290 | Randomness is returned as a string of bytes. */ | ||
291 | $rand = ""; | ||
292 | for ($a = 0; $a < $bytes; $a++) { | ||
293 | $rand .= chr(mt_rand(0, 255)); | ||
294 | } | ||
295 | return $rand; | ||
296 | } | ||
297 | |||
298 | protected static function randomFRead($bytes) { | ||
299 | /* Get the specified number of random bytes using a file handle | ||
300 | previously opened with UUID::initRandom(). | ||
301 | Randomness is returned as a string of bytes. */ | ||
302 | return fread(self::$randomSource, $bytes); | ||
303 | } | ||
304 | |||
305 | protected static function randomCOM($bytes) { | ||
306 | /* Get the specified number of random bytes using Windows' | ||
307 | randomness source via a COM object previously created by UUID::initRandom(). | ||
308 | Randomness is returned as a string of bytes. */ | ||
309 | return base64_decode(self::$randomSource->GetRandom($bytes,0)); // straight binary mysteriously doesn't work, hence the base64 | ||
310 | } | ||
311 | } | ||
312 | |||
313 | class UUIDException extends Exception { | ||
314 | } | ||