aboutsummaryrefslogtreecommitdiffstats
path: root/wsutil/base32.c
blob: 2c320a616d256ec22048ff191ea65b6885848a3d (plain)
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
/* base32.c
 * Base-32 conversion
 *
 * Wireshark - Network traffic analyzer
 * By Gerald Combs <gerald@wireshark.org>
 * Copyright 1998 Gerald Combs
 *
 * SPDX-License-Identifier: GPL-2.0+
 */

#include "config.h"

#include <glib.h>

#include <string.h>
#include "base32.h"

/*
 * Cjdns style base32 encoding
 */

/** Returned by ws_base32_encode() if the input is not valid base32. */
#define Base32_BAD_INPUT -1
/** Returned by ws_base32_encode() if the output buffer is too small. */
#define Base32_TOO_BIG -2

int ws_base32_decode(guint8* output, const guint32 outputLength,
						const guint8* in, const guint32 inputLength)
{
	guint32 outIndex = 0;
	guint32 inIndex = 0;
	guint32 work = 0;
	guint32 bits = 0;
	static const guint8* kChars = (guint8*) "0123456789bcdfghjklmnpqrstuvwxyz";
	while (inIndex < inputLength) {
		work |= ((unsigned) in[inIndex++]) << bits;
		bits += 8;
		while (bits >= 5) {
			if (outIndex >= outputLength) {
				return Base32_TOO_BIG;
			}
			output[outIndex++] = kChars[work & 31];
			bits -= 5;
			work >>= 5;
		}
	}
	if (bits) {
		if (outIndex >= outputLength) {
			return Base32_TOO_BIG;
		}
		output[outIndex++] = kChars[work & 31];
	}
	if (outIndex < outputLength) {
		output[outIndex] = '\0';
	}
	return outIndex;
}

/*
 * Editor modelines  -  http://www.wireshark.org/tools/modelines.html
 *
 * Local variables:
 * c-basic-offset: 8
 * tab-width: 8
 * indent-tabs-mode: t
 * End:
 *
 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
 * :indentSize=8:tabSize=8:noTabs=false:
 */