Skip to content

Commit

Permalink
Reorganize redbean EncodeBase32 code
Browse files Browse the repository at this point in the history
  • Loading branch information
pkulchenko committed Oct 9, 2023
1 parent e5e9761 commit a5cfb8f
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 51 deletions.
72 changes: 72 additions & 0 deletions net/http/base32.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
╞══════════════════════════════════════════════════════════════════════════════╡
│ Copyright 2021 Justine Alexandra Roberts Tunney │
│ │
│ Permission to use, copy, modify, and/or distribute this software for │
│ any purpose with or without fee is hereby granted, provided that the │
│ above copyright notice and this permission notice appear in all copies. │
│ │
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
│ PERFORMANCE OF THIS SOFTWARE. │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/macros.internal.h"
#include "libc/mem/mem.h"
#include "libc/str/str.h"

asm(".ident\t\"\\n\\n\
Apache License, Version 2.0\\n\
Copyright 2010 Google Inc.\"");
asm(".include \"libc/disclaimer.inc\"");

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
char* EncodeBase32(const char *s, size_t sl,
const char *a, size_t al,
size_t *ol) {
unassert(2 <= al && al <= 256);
size_t count = 0;
char *r;
int bl = tobits(al);
int mask = (1 << bl) - 1;
*ol = (sl * 8 + bl - 1) / bl; // calculate exact output length
if (!(r = malloc(*ol + 1))) {
*ol = 0;
return r;
}
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;
r[count++] = a[mask & (buffer >> bitsLeft)];
}
}
if (count < *ol) r[count] = '\000';
return r;
}
1 change: 1 addition & 0 deletions net/http/escape.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ char *EncodeLatin1(const char *, size_t, size_t *, int);
char *EncodeHttpHeaderValue(const char *, size_t, size_t *);
char *VisualizeControlCodes(const char *, size_t, size_t *);
char *IndentLines(const char *, size_t, size_t *, size_t);
char *EncodeBase32(const char *, size_t, const char, size_t, size_t *);
char *EncodeBase64(const char *, size_t, size_t *);
char *DecodeBase64(const char *, size_t, size_t *);

Expand Down
58 changes: 7 additions & 51 deletions tool/net/lfuncs.c
Original file line number Diff line number Diff line change
Expand Up @@ -605,61 +605,17 @@ 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);
size_t sl, al; // source/output and alphabet lengths
const char *s = luaL_checklstring(L, 1, &sl);
const char *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);
if (!(p = EncodeBase32(s, sl, a, al, &sl)))
return luaL_error(L, "out of memory");
lua_pushlstring(L, p, sl);
free(p);
return 1;
}

Expand Down

0 comments on commit a5cfb8f

Please sign in to comment.