ref: 9d97d20f6fa95b1f6ca455ac6a277b3bced5eb1c
parent: 9ddcbf1be2343ebb4d7853fecf8528e862def846
author: kvik <kvik@a-b.xyz>
date: Sat Aug 7 20:21:52 EDT 2021
misc: implement p9.{enc,dec}{16,32,64} bindings
--- a/base/base.c
+++ b/base/base.c
@@ -53,6 +53,13 @@
{"nsec", p9_nsec},
{"cleanname", p9_cleanname},
+ {"enc64", p9_enc64},
+ {"dec64", p9_dec64},
+ {"enc32", p9_enc32},
+ {"dec32", p9_dec32},
+ {"enc16", p9_enc16},
+ {"dec16", p9_dec16},
+
{nil, nil}
};
--- a/base/misc.c
+++ b/base/misc.c
@@ -58,3 +58,75 @@
lua_pushinteger(L, nsec());
return 1;
}
+
+static int
+decode(lua_State *L, int base)
+{
+ const char *in;
+ char *buf;
+ usize insz, bufsz, sz;
+ luaL_Buffer b;
+ int (*dec)(uchar*, int, char*, int);
+
+ in = luaL_checklstring(L, 1, &insz);
+ buf = luaL_buffinitsize(L, &b, insz+1);
+ switch(base){
+ case 64:
+ dec = dec64;
+ bufsz = 6 * (insz + 3) / 8;
+ break;
+ case 32:
+ dec = dec32;
+ bufsz = 5 * (insz + 7) / 8;
+ break;
+ case 16:
+ dec = dec16;
+ bufsz = 4 * (insz + 1) / 8;
+ break;
+ default:
+ return error(L, "unsupported base");
+ }
+ if((sz = dec((uchar*)buf, bufsz, in, insz)) == -1)
+ return error(L, "dec: failed");
+ luaL_pushresultsize(&b, sz);
+ return 1;
+}
+static int p9_dec64(lua_State *L) { return decode(L, 64); }
+static int p9_dec32(lua_State *L) { return decode(L, 32); }
+static int p9_dec16(lua_State *L) { return decode(L, 16); }
+
+static int
+encode(lua_State *L, int base)
+{
+ const char *in;
+ char *buf;
+ usize insz, bufsz, sz;
+ luaL_Buffer b;
+ int (*enc)(char*, int, uchar*, int);
+
+ in = luaL_checklstring(L, 1, &insz);
+ switch(base){
+ case 64:
+ enc = enc64;
+ bufsz = (insz + 3) * 8 / 6;
+ break;
+ case 32:
+ enc = enc32;
+ bufsz = (insz + 7) * 8 / 5;
+ break;
+ case 16:
+ enc = enc16;
+ bufsz = (insz + 1) * 8 / 4;
+ break;
+ default:
+ return error(L, "unsupported base");
+ }
+ buf = luaL_buffinitsize(L, &b, bufsz);
+ if((sz = enc(buf, bufsz, (uchar*)in, insz)) == -1)
+ return error(L, "enc: failed");
+ luaL_pushresultsize(&b, sz);
+ return 1;
+}
+static int p9_enc64(lua_State *L) { return encode(L, 64); }
+static int p9_enc32(lua_State *L) { return encode(L, 32); }
+static int p9_enc16(lua_State *L) { return encode(L, 16); }
--- a/test/test.lua
+++ b/test/test.lua
@@ -308,6 +308,23 @@
assert(p9.cleanname("/usr///./glenda/.") == "/usr/glenda")
end
+-- baseN encode / decode
+do
+ t = {"", "h", "he", "hel", "hell", "hello", "hello ", "hello w", "hello wo", "hello wor", "hello worl", "hello world"}
+ for _, s in ipairs(t) do
+ local enc, dec
+ s = string.rep(s, 100)
+ enc = assert(p9.enc64(s))
+ dec = assert(p9.dec64(enc))
+ assert(dec == s)
+ enc = assert(p9.enc32(s))
+ dec = assert(p9.dec32(enc))
+ assert(dec == s)
+ enc = assert(p9.enc16(s))
+ dec = assert(p9.dec16(enc))
+ assert(dec == s)
+ end
+end