-
Notifications
You must be signed in to change notification settings - Fork 2
/
Base32.php
81 lines (73 loc) · 1.81 KB
/
Base32.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
<?php
class Base32
{
const BITS_5_RIGHT = 31;
const CHARS = 'abcdefghijklmnopqrstuvwxyz234567'; // lower-case
public static function encode($data, $padRight = false)
{
$dataSize = strlen($data);
$res = '';
$remainder = 0;
$remainderSize = 0;
for ($i = 0; $i < $dataSize; $i++)
{
$b = ord($data[$i]);
$remainder = ($remainder << 8) | $b;
$remainderSize += 8;
while ($remainderSize > 4)
{
$remainderSize -= 5;
$c = $remainder & (self::BITS_5_RIGHT << $remainderSize);
$c >>= $remainderSize;
$res .= static::CHARS[$c];
}
}
if ($remainderSize > 0)
{
// remainderSize < 5:
$remainder <<= (5 - $remainderSize);
$c = $remainder & self::BITS_5_RIGHT;
$res .= static::CHARS[$c];
}
if ($padRight)
{
$padSize = (8 - ceil(($dataSize % 5) * 8 / 5)) % 8;
$res .= str_repeat('=', $padSize);
}
return $res;
}
public static function decode($data)
{
$data = rtrim($data, "=\x20\t\n\r\0\x0B");
$dataSize = strlen($data);
$buf = 0;
$bufSize = 0;
$res = '';
$charMap = array_flip(str_split(static::CHARS)); // char=>value map
$charMap += array_flip(str_split(strtoupper(static::CHARS))); // add upper-case alternatives
for ($i = 0; $i < $dataSize; $i++)
{
$c = $data[$i];
if (!isset($charMap[$c]))
{
if ($c == " " || $c == "\r" || $c == "\n" || $c == "\t")
continue; // ignore these safe characters
throw new Exception('Encoded string contains unexpected char #'.ord($c)." at offset $i (using improper alphabet?)");
}
$b = $charMap[$c];
$buf = ($buf << 5) | $b;
$bufSize += 5;
if ($bufSize > 7)
{
$bufSize -= 8;
$b = ($buf & (0xff << $bufSize)) >> $bufSize;
$res .= chr($b);
}
}
return $res;
}
}
class Base32hex extends Base32
{
const CHARS = '0123456789abcdefghijklmnopqrstuv'; // lower-case
}