Skip to content

Commit

Permalink
Add EncodeBase32() to Redbean
Browse files Browse the repository at this point in the history
  • Loading branch information
pkulchenko committed Oct 5, 2023
1 parent af7cb3c commit e5e9761
Show file tree
Hide file tree
Showing 5 changed files with 69 additions and 0 deletions.
5 changes: 5 additions & 0 deletions test/tool/net/lfuncs_test.lua
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,11 @@ assert(bin(0x1940efe9d47ae889) == "0b0001100101000000111011111110100111010100011
assert(EncodeHex("\1\2\3\4\255") == "01020304ff")
assert(DecodeHex("01020304ff") == "\1\2\3\4\255")

assert(EncodeBase32("123456") == "64s36d1n6r")
assert(EncodeBase32("12") == "64s0")
assert(EncodeBase32("\33", "01") == "00100001")
assert(EncodeBase32("\33", "0123456789abcdef") == "21")

assert(EscapeHtml(nil) == nil)
assert(EscapeHtml("?hello&there<>") == "?hello&amp;there&lt;&gt;")

Expand Down
4 changes: 4 additions & 0 deletions tool/net/help.txt
Original file line number Diff line number Diff line change
Expand Up @@ -737,6 +737,10 @@ FUNCTIONS
Turns ASCII base-16 hexadecimal byte string into binary string,
case-insensitively. Non-hex characters may not appear in string.

EncodeBase32(binary:str[, alphabet:str]) → ascii:str
Turns binary into ASCII using provided alphabet (using Crockford's
base32 encoding by default).

DecodeBase64(ascii:str) → binary:str
Turns ASCII into binary, in a permissive way that ignores
characters outside the base64 alphabet, such as whitespace. See
Expand Down
58 changes: 58 additions & 0 deletions tool/net/lfuncs.c
Original file line number Diff line number Diff line change
Expand Up @@ -605,6 +605,64 @@ int LuaEncodeLatin1(lua_State *L) {
}
}

int tobits(int b) {
int bits = 0; while (b && (b >>= 1)) bits++;
return bits;
}

// the next function is based on
// https://github.com/google/google-authenticator-libpam/blob/master/src/base32.c
// Copyright 2010 Google Inc.; Author: Markus Gutschke
// licensed under Apache License, Version 2.0
// p already has ol bytes allocated
// which is enough to store encoded result
char* base32pcpy(char *p, const char *s, size_t sl,
const char *a, size_t al,
size_t ol) {
size_t count = 0;
int bl = tobits(al);
int mask = (1 << bl) - 1;
if (sl > 0) {
int buffer = s[0];
size_t next = 1;
int bitsLeft = 8;
while (count < ol && (bitsLeft > 0 || next < sl)) {
if (bitsLeft < bl) {
if (next < sl) {
buffer <<= 8;
buffer |= s[next++] & 0xFF;
bitsLeft += 8;
} else {
int pad = bl - bitsLeft;
buffer <<= pad;
bitsLeft += pad;
}
}
bitsLeft -= bl;
p[count++] = a[mask & (buffer >> bitsLeft)];
}
}
if (count < ol) p[count] = '\000';
return p;
}

int LuaEncodeBase32(lua_State *L) {
char *p;
size_t sl, al, ol; // source, alphabet, and output lengths
const char *s, *a;
luaL_Buffer buf;
s = luaL_checklstring(L, 1, &sl);
a = luaL_optlstring(L, 2, "0123456789abcdefghjkmnpqrstvwxyz", &al);
if (al & (al - 1) || al > 256 || al < 2)
return luaL_error(L, "alphabet length is not a power of 2 in range 2..256");
ol = tobits(al);
ol = (sl * 8 + ol - 1) / ol; // calculate exact output length
p = luaL_buffinitsize(L, &buf, ol);
base32pcpy(p, s, sl, a, al, ol);
luaL_pushresultsize(&buf, ol);
return 1;
}

int LuaEncodeHex(lua_State *L) {
char *p;
size_t n;
Expand Down
1 change: 1 addition & 0 deletions tool/net/lfuncs.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ int LuaDecodeBase64(lua_State *);
int LuaDecodeHex(lua_State *);
int LuaDecodeLatin1(lua_State *);
int LuaDeflate(lua_State *);
int LuaEncodeBase32(lua_State *);
int LuaEncodeBase64(lua_State *);
int LuaEncodeHex(lua_State *);
int LuaEncodeLatin1(lua_State *);
Expand Down
1 change: 1 addition & 0 deletions tool/net/redbean.c
Original file line number Diff line number Diff line change
Expand Up @@ -5132,6 +5132,7 @@ static const luaL_Reg kLuaFuncs[] = {
{"DecodeJson", LuaDecodeJson}, //
{"DecodeLatin1", LuaDecodeLatin1}, //
{"Deflate", LuaDeflate}, //
{"EncodeBase32", LuaEncodeBase32}, //
{"EncodeBase64", LuaEncodeBase64}, //
{"EncodeHex", LuaEncodeHex}, //
{"EncodeJson", LuaEncodeJson}, //
Expand Down

0 comments on commit e5e9761

Please sign in to comment.