1<?php
2
3define('BASE32_ALPHABET', '0123456789bcdfghjklmnpqrstuvwxyz');
4define('BASE32_NBITS',    5);
5
6function base32_encode($input)
7{
8	$output   = '';
9
10	$buffer = ['size'=>BASE32_NBITS, 'callback'=> function($x) use(&$output) { $output .= BASE32_ALPHABET[$x]; }];
11	$length = strlen($input);
12	for ($i = 0; $i < $length; $i++)
13	{
14		$char = ord($input[$i]);
15		base32_buffer_add($buffer, $char, 8);
16	}
17
18	if ($buffer) { base32_buffer_add($buffer, 0, 8); $length--; }
19	$output .= str_repeat('=', $length % 3);
20
21	return $output;
22}
23
24function base32_decode($input)
25{
26	$input  = preg_replace('#\s#', '', $input);
27	$output = '';
28
29	$buffer = ['size'=>8, 'callback'=> function($x) use(&$output) { $output .= chr($x); }];
30	for ($i = 0; $i < strlen($input); $i++)
31	if ($input[$i] != '=')
32	{
33		$char = strpos(BASE32_ALPHABET, $input[$i]);
34		base32_buffer_add($buffer, $char, BASE32_NBITS);
35	}
36
37	return $output;
38}
39
40function base32_buffer_add(&$buffer, $char, $char_size)
41{
42	@$buffer['data']      |= $char << @$buffer['data_size'];
43	@$buffer['data_size'] += $char_size;
44	while ($buffer['data_size'] > $buffer['size'])
45	{
46		$mask = pow(2, $buffer['size']) - 1;
47		$char = $buffer['data'] & $mask;
48		$buffer['callback']($char);
49		$buffer['data'] >>= $buffer['size'];
50		$buffer['data_size'] -= $buffer['size'];
51	}
52}
53