|
|
@@ -503,6 +503,130 @@ int l_str_fromBase64(lua_State *L) {
|
|
|
return 1;
|
|
|
}
|
|
|
|
|
|
+////////////////////////////////////////////
|
|
|
+//// BASE32 /////
|
|
|
+////////////////////////////////////////////
|
|
|
+// Copyright 2010 Google Inc.
|
|
|
+// Author: Markus Gutschke
|
|
|
+// Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
+// you may not use this file except in compliance with the License.
|
|
|
+// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
|
|
+
|
|
|
+int luat_str_base32_decode(const uint8_t *encoded, uint8_t *result, int bufSize) {
|
|
|
+ int buffer = 0;
|
|
|
+ int bitsLeft = 0;
|
|
|
+ int count = 0;
|
|
|
+ for (const uint8_t *ptr = encoded; count < bufSize && *ptr; ++ptr) {
|
|
|
+ uint8_t ch = *ptr;
|
|
|
+ if (ch == ' ' || ch == '\t' || ch == '\r' || ch == '\n' || ch == '-') {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ buffer <<= 5;
|
|
|
+
|
|
|
+ // Deal with commonly mistyped characters
|
|
|
+ if (ch == '0') {
|
|
|
+ ch = 'O';
|
|
|
+ } else if (ch == '1') {
|
|
|
+ ch = 'L';
|
|
|
+ } else if (ch == '8') {
|
|
|
+ ch = 'B';
|
|
|
+ }
|
|
|
+
|
|
|
+ // Look up one base32 digit
|
|
|
+ if ((ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z')) {
|
|
|
+ ch = (ch & 0x1F) - 1;
|
|
|
+ } else if (ch >= '2' && ch <= '7') {
|
|
|
+ ch -= '2' - 26;
|
|
|
+ } else {
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+
|
|
|
+ buffer |= ch;
|
|
|
+ bitsLeft += 5;
|
|
|
+ if (bitsLeft >= 8) {
|
|
|
+ result[count++] = buffer >> (bitsLeft - 8);
|
|
|
+ bitsLeft -= 8;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (count < bufSize) {
|
|
|
+ result[count] = '\000';
|
|
|
+ }
|
|
|
+ return count;
|
|
|
+}
|
|
|
+
|
|
|
+int luat_str_base32_encode(const uint8_t *data, int length, uint8_t *result,
|
|
|
+ int bufSize) {
|
|
|
+ if (length < 0 || length > (1 << 28)) {
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+ int count = 0;
|
|
|
+ if (length > 0) {
|
|
|
+ int buffer = data[0];
|
|
|
+ int next = 1;
|
|
|
+ int bitsLeft = 8;
|
|
|
+ while (count < bufSize && (bitsLeft > 0 || next < length)) {
|
|
|
+ if (bitsLeft < 5) {
|
|
|
+ if (next < length) {
|
|
|
+ buffer <<= 8;
|
|
|
+ buffer |= data[next++] & 0xFF;
|
|
|
+ bitsLeft += 8;
|
|
|
+ } else {
|
|
|
+ int pad = 5 - bitsLeft;
|
|
|
+ buffer <<= pad;
|
|
|
+ bitsLeft += pad;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ int index = 0x1F & (buffer >> (bitsLeft - 5));
|
|
|
+ bitsLeft -= 5;
|
|
|
+ result[count++] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567"[index];
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (count < bufSize) {
|
|
|
+ result[count] = '\000';
|
|
|
+ }
|
|
|
+ return count;
|
|
|
+}
|
|
|
+
|
|
|
+/*
|
|
|
+将字符串进行base32编码
|
|
|
+@api string.toBase32(str)
|
|
|
+@string 需要转换的字符串
|
|
|
+@return string 解码后的字符串,如果解码失败会返回0长度字符串
|
|
|
+*/
|
|
|
+int l_str_toBase32(lua_State *L) {
|
|
|
+ size_t len = 0;
|
|
|
+ const char* str = luaL_checklstring(L, 1, &len);
|
|
|
+ if (len == 0) {
|
|
|
+ lua_pushstring(L, "");
|
|
|
+ return 1;
|
|
|
+ }
|
|
|
+ luaL_Buffer buff = {0};
|
|
|
+ luaL_buffinitsize(L, &buff, len * 2);
|
|
|
+ int rl = luat_str_base32_encode((const uint8_t * )str,len,buff.b,buff.size);
|
|
|
+ luaL_pushresultsize(&buff, rl);
|
|
|
+ return 1;
|
|
|
+}
|
|
|
+
|
|
|
+/*
|
|
|
+将字符串进行base32解码
|
|
|
+@api string.fromBase32(str)
|
|
|
+@string 需要转换的字符串
|
|
|
+@return string 解码后的字符串,如果解码失败会返回0长度字符串
|
|
|
+*/
|
|
|
+int l_str_fromBase32(lua_State *L) {
|
|
|
+ size_t len = 0;
|
|
|
+ const char* str = luaL_checklstring(L, 1, &len);
|
|
|
+ if (len == 0) {
|
|
|
+ lua_pushstring(L, "");
|
|
|
+ return 1;
|
|
|
+ }
|
|
|
+ luaL_Buffer buff = {0};
|
|
|
+ luaL_buffinitsize(L, &buff, len + 1);
|
|
|
+ int rl = luat_str_base32_decode((const uint8_t * )str,buff.b,buff.size);
|
|
|
+ luaL_pushresultsize(&buff, rl);
|
|
|
+ return 1;
|
|
|
+}
|
|
|
+
|
|
|
/*
|
|
|
判断字符串前缀
|
|
|
@api string.startsWith(str, prefix)
|