]>
Commit | Line | Data |
---|---|---|
fb70f26e AD |
1 | <?php |
2 | ||
3 | /** | |
4 | * Encode in Base32 based on RFC 4648. | |
5 | * Requires 20% more space than base64 | |
6 | * Great for case-insensitive filesystems like Windows and URL's (except for = char which can be excluded using the pad option for urls) | |
7 | * | |
8 | * @package default | |
9 | * @author Bryan Ruiz | |
10 | **/ | |
11 | class Base32 { | |
12 | ||
13 | private static $map = array( | |
14 | 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', // 7 | |
15 | 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', // 15 | |
16 | 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', // 23 | |
17 | 'Y', 'Z', '2', '3', '4', '5', '6', '7', // 31 | |
18 | '=' // padding char | |
19 | ); | |
20 | ||
21 | private static $flippedMap = array( | |
22 | 'A'=>'0', 'B'=>'1', 'C'=>'2', 'D'=>'3', 'E'=>'4', 'F'=>'5', 'G'=>'6', 'H'=>'7', | |
23 | 'I'=>'8', 'J'=>'9', 'K'=>'10', 'L'=>'11', 'M'=>'12', 'N'=>'13', 'O'=>'14', 'P'=>'15', | |
24 | 'Q'=>'16', 'R'=>'17', 'S'=>'18', 'T'=>'19', 'U'=>'20', 'V'=>'21', 'W'=>'22', 'X'=>'23', | |
25 | 'Y'=>'24', 'Z'=>'25', '2'=>'26', '3'=>'27', '4'=>'28', '5'=>'29', '6'=>'30', '7'=>'31' | |
26 | ); | |
27 | ||
28 | /** | |
29 | * Use padding false when encoding for urls | |
30 | * | |
31 | * @return base32 encoded string | |
32 | * @author Bryan Ruiz | |
33 | **/ | |
34 | public static function encode($input, $padding = true) { | |
35 | if(empty($input)) return ""; | |
36 | $input = str_split($input); | |
37 | $binaryString = ""; | |
38 | for($i = 0; $i < count($input); $i++) { | |
39 | $binaryString .= str_pad(base_convert(ord($input[$i]), 10, 2), 8, '0', STR_PAD_LEFT); | |
40 | } | |
41 | $fiveBitBinaryArray = str_split($binaryString, 5); | |
42 | $base32 = ""; | |
43 | $i=0; | |
44 | while($i < count($fiveBitBinaryArray)) { | |
45 | $base32 .= self::$map[base_convert(str_pad($fiveBitBinaryArray[$i], 5,'0'), 2, 10)]; | |
46 | $i++; | |
47 | } | |
48 | if($padding && ($x = strlen($binaryString) % 40) != 0) { | |
49 | if($x == 8) $base32 .= str_repeat(self::$map[32], 6); | |
50 | else if($x == 16) $base32 .= str_repeat(self::$map[32], 4); | |
51 | else if($x == 24) $base32 .= str_repeat(self::$map[32], 3); | |
52 | else if($x == 32) $base32 .= self::$map[32]; | |
53 | } | |
54 | return $base32; | |
55 | } | |
56 | ||
57 | public static function decode($input) { | |
58 | if(empty($input)) return; | |
59 | $paddingCharCount = substr_count($input, self::$map[32]); | |
60 | $allowedValues = array(6,4,3,1,0); | |
61 | if(!in_array($paddingCharCount, $allowedValues)) return false; | |
62 | for($i=0; $i<4; $i++){ | |
63 | if($paddingCharCount == $allowedValues[$i] && | |
64 | substr($input, -($allowedValues[$i])) != str_repeat(self::$map[32], $allowedValues[$i])) return false; | |
65 | } | |
66 | $input = str_replace('=','', $input); | |
67 | $input = str_split($input); | |
68 | $binaryString = ""; | |
69 | for($i=0; $i < count($input); $i = $i+8) { | |
70 | $x = ""; | |
71 | if(!in_array($input[$i], self::$map)) return false; | |
72 | for($j=0; $j < 8; $j++) { | |
73 | $x .= str_pad(base_convert(@self::$flippedMap[@$input[$i + $j]], 10, 2), 5, '0', STR_PAD_LEFT); | |
74 | } | |
75 | $eightBits = str_split($x, 8); | |
76 | for($z = 0; $z < count($eightBits); $z++) { | |
77 | $binaryString .= ( ($y = chr(base_convert($eightBits[$z], 2, 10))) || ord($y) == 48 ) ? $y:""; | |
78 | } | |
79 | } | |
80 | return $binaryString; | |
81 | } | |
82 | } | |
83 |