Skip to content

Instantly share code, notes, and snippets.

@starwing
Last active November 23, 2019 03:28
Show Gist options
  • Save starwing/9781a8e16be29d514926102487777dcd to your computer and use it in GitHub Desktop.
Save starwing/9781a8e16be29d514926102487777dcd to your computer and use it in GitHub Desktop.
A simple MD5 module for Lua
#ifdef _MSC_VER
# define _CRT_SECURE_NO_WARNINGS
# define _CRT_NONSTDC_NO_WARNINGS
#endif
#define LUA_LIB
#include <lua.h>
#include <lauxlib.h>
#if LUA_VERSION_NUM < 502
# define luaL_setfuncs(L,l,n) (assert(n==0), luaL_register(L,NULL,l))
# define luaL_setmetatable(L, name) \
(luaL_getmetatable((L), (name)), lua_setmetatable(L, -2))
#endif
#include <stdint.h>
#include <string.h>
typedef struct {
uint64_t bytes;
uint32_t a, b, c, d;
uint8_t buffer[64];
} md5_t;
#define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
#define G(x, y, z) ((y) ^ ((z) & ((x) ^ (y))))
#define H(x, y, z) ((x) ^ (y) ^ (z))
#define I(x, y, z) ((y) ^ ((x) | ~(z)))
#define STEP(f, a, b, c, d, x, t, s) \
(a) += f((b), (c), (d)) + (x) + (t); \
(a) = (((a) << (s)) | (((a) & 0xffffffff) >> (32 - (s)))); \
(a) += (b)
#define SET(n) \
(block[n] = \
((uint32_t)p[n*4 ] ) | \
((uint32_t)p[n*4 + 1] << 8) | \
((uint32_t)p[n*4 + 2] << 16) | \
((uint32_t)p[n*4 + 3] << 24))
#define GET(n) block[n]
#define DUMP(r, n, a) \
r[n*4 ] = (uint8_t)((a) ); \
r[n*4 + 1] = (uint8_t)((a) >> 8); \
r[n*4 + 2] = (uint8_t)((a) >> 16); \
r[n*4 + 3] = (uint8_t)((a) >> 24);
static const uint8_t *md5_body(md5_t *ctx, const uint8_t *data, size_t size) {
const uint8_t *p = (const uint8_t*)data;
uint32_t a, b, c, d;
a = ctx->a, b = ctx->b, c = ctx->c, d = ctx->d;
do {
uint32_t oa = a, ob = b, oc = c, od = d;
uint32_t block[16];
/* Transformations */
STEP(F, a, b, c, d, SET(0), 0xd76aa478, 7);
STEP(F, d, a, b, c, SET(1), 0xe8c7b756, 12);
STEP(F, c, d, a, b, SET(2), 0x242070db, 17);
STEP(F, b, c, d, a, SET(3), 0xc1bdceee, 22);
STEP(F, a, b, c, d, SET(4), 0xf57c0faf, 7);
STEP(F, d, a, b, c, SET(5), 0x4787c62a, 12);
STEP(F, c, d, a, b, SET(6), 0xa8304613, 17);
STEP(F, b, c, d, a, SET(7), 0xfd469501, 22);
STEP(F, a, b, c, d, SET(8), 0x698098d8, 7);
STEP(F, d, a, b, c, SET(9), 0x8b44f7af, 12);
STEP(F, c, d, a, b, SET(10), 0xffff5bb1, 17);
STEP(F, b, c, d, a, SET(11), 0x895cd7be, 22);
STEP(F, a, b, c, d, SET(12), 0x6b901122, 7);
STEP(F, d, a, b, c, SET(13), 0xfd987193, 12);
STEP(F, c, d, a, b, SET(14), 0xa679438e, 17);
STEP(F, b, c, d, a, SET(15), 0x49b40821, 22);
STEP(G, a, b, c, d, GET(1), 0xf61e2562, 5);
STEP(G, d, a, b, c, GET(6), 0xc040b340, 9);
STEP(G, c, d, a, b, GET(11), 0x265e5a51, 14);
STEP(G, b, c, d, a, GET(0), 0xe9b6c7aa, 20);
STEP(G, a, b, c, d, GET(5), 0xd62f105d, 5);
STEP(G, d, a, b, c, GET(10), 0x02441453, 9);
STEP(G, c, d, a, b, GET(15), 0xd8a1e681, 14);
STEP(G, b, c, d, a, GET(4), 0xe7d3fbc8, 20);
STEP(G, a, b, c, d, GET(9), 0x21e1cde6, 5);
STEP(G, d, a, b, c, GET(14), 0xc33707d6, 9);
STEP(G, c, d, a, b, GET(3), 0xf4d50d87, 14);
STEP(G, b, c, d, a, GET(8), 0x455a14ed, 20);
STEP(G, a, b, c, d, GET(13), 0xa9e3e905, 5);
STEP(G, d, a, b, c, GET(2), 0xfcefa3f8, 9);
STEP(G, c, d, a, b, GET(7), 0x676f02d9, 14);
STEP(G, b, c, d, a, GET(12), 0x8d2a4c8a, 20);
STEP(H, a, b, c, d, GET(5), 0xfffa3942, 4);
STEP(H, d, a, b, c, GET(8), 0x8771f681, 11);
STEP(H, c, d, a, b, GET(11), 0x6d9d6122, 16);
STEP(H, b, c, d, a, GET(14), 0xfde5380c, 23);
STEP(H, a, b, c, d, GET(1), 0xa4beea44, 4);
STEP(H, d, a, b, c, GET(4), 0x4bdecfa9, 11);
STEP(H, c, d, a, b, GET(7), 0xf6bb4b60, 16);
STEP(H, b, c, d, a, GET(10), 0xbebfbc70, 23);
STEP(H, a, b, c, d, GET(13), 0x289b7ec6, 4);
STEP(H, d, a, b, c, GET(0), 0xeaa127fa, 11);
STEP(H, c, d, a, b, GET(3), 0xd4ef3085, 16);
STEP(H, b, c, d, a, GET(6), 0x04881d05, 23);
STEP(H, a, b, c, d, GET(9), 0xd9d4d039, 4);
STEP(H, d, a, b, c, GET(12), 0xe6db99e5, 11);
STEP(H, c, d, a, b, GET(15), 0x1fa27cf8, 16);
STEP(H, b, c, d, a, GET(2), 0xc4ac5665, 23);
STEP(I, a, b, c, d, GET(0), 0xf4292244, 6);
STEP(I, d, a, b, c, GET(7), 0x432aff97, 10);
STEP(I, c, d, a, b, GET(14), 0xab9423a7, 15);
STEP(I, b, c, d, a, GET(5), 0xfc93a039, 21);
STEP(I, a, b, c, d, GET(12), 0x655b59c3, 6);
STEP(I, d, a, b, c, GET(3), 0x8f0ccc92, 10);
STEP(I, c, d, a, b, GET(10), 0xffeff47d, 15);
STEP(I, b, c, d, a, GET(1), 0x85845dd1, 21);
STEP(I, a, b, c, d, GET(8), 0x6fa87e4f, 6);
STEP(I, d, a, b, c, GET(15), 0xfe2ce6e0, 10);
STEP(I, c, d, a, b, GET(6), 0xa3014314, 15);
STEP(I, b, c, d, a, GET(13), 0x4e0811a1, 21);
STEP(I, a, b, c, d, GET(4), 0xf7537e82, 6);
STEP(I, d, a, b, c, GET(11), 0xbd3af235, 10);
STEP(I, c, d, a, b, GET(2), 0x2ad7d2bb, 15);
STEP(I, b, c, d, a, GET(9), 0xeb86d391, 21);
a += oa, b += ob, c += oc, d += od;
p += 64;
} while (size -= 64);
ctx->a = a, ctx->b = b, ctx->c = c, ctx->d = d;
return p;
}
static void md5_init(md5_t *ctx) {
ctx->a = 0x67452301;
ctx->b = 0xefcdab89;
ctx->c = 0x98badcfe;
ctx->d = 0x10325476;
ctx->bytes = 0;
}
static void md5_update(md5_t *ctx, const void *data, size_t size) {
size_t used = ctx->bytes & 0x3f;
ctx->bytes += size;
if (used) {
size_t free = 64 - used;
if (size < free) {
memcpy(&ctx->buffer[used], data, size);
return;
}
memcpy(&ctx->buffer[used], data, free);
data = (uint8_t*)data + free;
size -= free;
md5_body(ctx, ctx->buffer, 64);
}
if (size >= 64) {
data = md5_body(ctx, data, size & ~(size_t) 0x3f);
size &= 0x3f;
}
memcpy(ctx->buffer, data, size);
}
static void md5_finish(md5_t *ctx, uint8_t result[16]) {
size_t used = ctx->bytes & 0x3f;
size_t free = 64 - used - 1;
ctx->buffer[used++] = 0x80;
if (free < 8) {
memset(&ctx->buffer[used], 0, free);
md5_body(ctx, ctx->buffer, 64);
used = 0, free = 64;
}
memset(&ctx->buffer[used], 0, free - 8);
ctx->bytes <<= 3;
DUMP(ctx->buffer, 14, ctx->bytes );
DUMP(ctx->buffer, 15, ctx->bytes >> 32);
md5_body(ctx, ctx->buffer, 64);
DUMP(result, 0, ctx->a);
DUMP(result, 1, ctx->b);
DUMP(result, 2, ctx->c);
DUMP(result, 3, ctx->d);
}
#define MD5_TYPE "md5.Object"
static void update(md5_t *md5, lua_State *L, int i, int top) {
for (; i <= top; ++i) {
size_t len;
const char *s = luaL_checklstring(L, i, &len);
md5_update(md5, s, len);
}
}
static int Lnew(lua_State *L) {
int top = lua_gettop(L);
md5_t *md5 = (md5_t*)lua_newuserdata(L, sizeof(md5_t));
md5_init(md5);
luaL_setmetatable(L, MD5_TYPE);
update(md5, L, 1, top);
return 1;
}
static int Lupdate(lua_State *L) {
md5_t *md5 = (md5_t*)luaL_checkudata(L, 1, MD5_TYPE);
update(md5, L, 2, lua_gettop(L));
lua_settop(L, 1);
return 1;
}
static int Lfinish(lua_State *L) {
md5_t *md5 = (md5_t*)luaL_checkudata(L, 1, MD5_TYPE);
uint8_t result[16];
update(md5, L, 2, lua_gettop(L));
md5_finish(md5, result);
md5_init(md5);
lua_pushlstring(L, (const char*)result, 16);
return 1;
}
static int push_hexa(lua_State *L, const char *s, size_t len) {
const char *hexa = "0123456789ABCDEF";
size_t i;
luaL_Buffer B;
luaL_buffinit(L, &B);
for (i = 0; i < len; ++i) {
char *p = luaL_prepbuffer(&B);
*p++ = hexa[(s[i] >> 4) & 0xF];
*p++ = hexa[(s[i] >> 0) & 0xF];
luaL_addsize(&B, 2);
}
luaL_pushresult(&B);
return 1;
}
static void sum(lua_State *L, uint8_t result[16]) {
md5_t md5;
md5_init(&md5);
update(&md5, L, 1, lua_gettop(L));
md5_finish(&md5, result);
}
static int Lsum(lua_State *L) {
uint8_t result[16];
sum(L, result);
lua_pushlstring(L, (const char*)result, 16);
return 1;
}
static int Lsumhexa(lua_State *L) {
uint8_t result[16];
sum(L, result);
return push_hexa(L, (const char*)result, 16);
}
static int Ltohex(lua_State *L) {
size_t len;
const char *s = luaL_checklstring(L, 1, &len);
return push_hexa(L, s, len);
}
LUALIB_API int luaopen_md5(lua_State *L) {
luaL_Reg libs[] = {
#define ENTRY(name) { #name, L##name }
ENTRY(new),
ENTRY(sum),
ENTRY(sumhexa),
ENTRY(tohex),
ENTRY(update),
ENTRY(finish),
#undef ENTRY
{ NULL, NULL }
};
if (luaL_newmetatable(L, MD5_TYPE)) {
luaL_setfuncs(L, libs, 0);
lua_pushvalue(L, -1);
lua_setfield(L, -2, "__index");
}
return 1;
}
/* cc: flags+='-O3 -ggdb -pedantic -std=c90 -Wall -Wextra --coverage'
* maccc: flags+='-shared -undefined dynamic_lookup' output='md5.so'
* win32cc: flags+='-s -mdll -DLUA_BUILD_AS_DLL ' output='md5.dll' libs+='-llua53' */
#ifdef _MSC_VER
# define _CRT_SECURE_NO_WARNINGS
# define _CRT_NONSTDC_NO_WARNINGS
#endif
#define LUA_LIB
#include <lua.h>
#include <lauxlib.h>
#if LUA_VERSION_NUM < 502
# define luaL_setfuncs(L,l,n) (assert(n==0), luaL_register(L,NULL,l))
# define luaL_setmetatable(L, name) \
(luaL_getmetatable((L), (name)), lua_setmetatable(L, -2))
#endif
#include <stdint.h>
#include <string.h>
typedef struct {
uint64_t bytes;
uint32_t a, b, c, d, e, f;
uint8_t buffer[64];
} sha1_t;
#define F(b, c, d) (((b) & (c)) | ((~(b)) & (d)))
#define G(b, c, d) ((b) ^ (c) ^ (d))
#define H(b, c, d) (((b) & (c)) | ((b) & (d)) | ((c) & (d)))
#define I(b, c, d) G(b, c, d)
#define ROTATE(bits, word) (((word) << (bits)) | ((word) >> (32 - (bits))))
#define STEP(f, a, b, c, d, e, w, t) \
temp = ROTATE(5, (a)) + f((b), (c), (d)) + (e) + (w) + (t); \
(e) = (d); (d) = (c); \
(c) = ROTATE(30, (b)); \
(b) = (a); (a) = temp;
#define GET(n) \
((uint32_t)p[n*4 + 3] | \
((uint32_t)p[n*4 + 2] << 8) | \
((uint32_t)p[n*4 + 1] << 16) | \
((uint32_t)p[n*4 ] << 24))
#define DUMP(r, n, a) \
r[n*4 ] = (uint8_t)((a) >> 24); \
r[n*4 + 1] = (uint8_t)((a) >> 16); \
r[n*4 + 2] = (uint8_t)((a) >> 8); \
r[n*4 + 3] = (uint8_t)((a) );
static const uint8_t *sha1_body(sha1_t *ctx, const void *data, size_t size) {
const uint8_t *p = (const uint8_t*)data;
uint32_t a, b, c, d, e, temp;
a = ctx->a, b = ctx->b, c = ctx->c, d = ctx->d, e = ctx->e;
do {
uint32_t oa = a, ob = b, oc = c, od = d, oe = e;
uint32_t words[80];
size_t i;
/* Load data block into the words array */
for (i = 0; i < 16; i++)
words[i] = GET(i);
for (i = 16; i < 80; i++)
words[i] = ROTATE(1, words[i - 3]
^ words[i - 8]
^ words[i - 14]
^ words[i - 16]);
/* Transformations */
STEP(F, a, b, c, d, e, words[0], 0x5a827999);
STEP(F, a, b, c, d, e, words[1], 0x5a827999);
STEP(F, a, b, c, d, e, words[2], 0x5a827999);
STEP(F, a, b, c, d, e, words[3], 0x5a827999);
STEP(F, a, b, c, d, e, words[4], 0x5a827999);
STEP(F, a, b, c, d, e, words[5], 0x5a827999);
STEP(F, a, b, c, d, e, words[6], 0x5a827999);
STEP(F, a, b, c, d, e, words[7], 0x5a827999);
STEP(F, a, b, c, d, e, words[8], 0x5a827999);
STEP(F, a, b, c, d, e, words[9], 0x5a827999);
STEP(F, a, b, c, d, e, words[10], 0x5a827999);
STEP(F, a, b, c, d, e, words[11], 0x5a827999);
STEP(F, a, b, c, d, e, words[12], 0x5a827999);
STEP(F, a, b, c, d, e, words[13], 0x5a827999);
STEP(F, a, b, c, d, e, words[14], 0x5a827999);
STEP(F, a, b, c, d, e, words[15], 0x5a827999);
STEP(F, a, b, c, d, e, words[16], 0x5a827999);
STEP(F, a, b, c, d, e, words[17], 0x5a827999);
STEP(F, a, b, c, d, e, words[18], 0x5a827999);
STEP(F, a, b, c, d, e, words[19], 0x5a827999);
STEP(G, a, b, c, d, e, words[20], 0x6ed9eba1);
STEP(G, a, b, c, d, e, words[21], 0x6ed9eba1);
STEP(G, a, b, c, d, e, words[22], 0x6ed9eba1);
STEP(G, a, b, c, d, e, words[23], 0x6ed9eba1);
STEP(G, a, b, c, d, e, words[24], 0x6ed9eba1);
STEP(G, a, b, c, d, e, words[25], 0x6ed9eba1);
STEP(G, a, b, c, d, e, words[26], 0x6ed9eba1);
STEP(G, a, b, c, d, e, words[27], 0x6ed9eba1);
STEP(G, a, b, c, d, e, words[28], 0x6ed9eba1);
STEP(G, a, b, c, d, e, words[29], 0x6ed9eba1);
STEP(G, a, b, c, d, e, words[30], 0x6ed9eba1);
STEP(G, a, b, c, d, e, words[31], 0x6ed9eba1);
STEP(G, a, b, c, d, e, words[32], 0x6ed9eba1);
STEP(G, a, b, c, d, e, words[33], 0x6ed9eba1);
STEP(G, a, b, c, d, e, words[34], 0x6ed9eba1);
STEP(G, a, b, c, d, e, words[35], 0x6ed9eba1);
STEP(G, a, b, c, d, e, words[36], 0x6ed9eba1);
STEP(G, a, b, c, d, e, words[37], 0x6ed9eba1);
STEP(G, a, b, c, d, e, words[38], 0x6ed9eba1);
STEP(G, a, b, c, d, e, words[39], 0x6ed9eba1);
STEP(H, a, b, c, d, e, words[40], 0x8f1bbcdc);
STEP(H, a, b, c, d, e, words[41], 0x8f1bbcdc);
STEP(H, a, b, c, d, e, words[42], 0x8f1bbcdc);
STEP(H, a, b, c, d, e, words[43], 0x8f1bbcdc);
STEP(H, a, b, c, d, e, words[44], 0x8f1bbcdc);
STEP(H, a, b, c, d, e, words[45], 0x8f1bbcdc);
STEP(H, a, b, c, d, e, words[46], 0x8f1bbcdc);
STEP(H, a, b, c, d, e, words[47], 0x8f1bbcdc);
STEP(H, a, b, c, d, e, words[48], 0x8f1bbcdc);
STEP(H, a, b, c, d, e, words[49], 0x8f1bbcdc);
STEP(H, a, b, c, d, e, words[50], 0x8f1bbcdc);
STEP(H, a, b, c, d, e, words[51], 0x8f1bbcdc);
STEP(H, a, b, c, d, e, words[52], 0x8f1bbcdc);
STEP(H, a, b, c, d, e, words[53], 0x8f1bbcdc);
STEP(H, a, b, c, d, e, words[54], 0x8f1bbcdc);
STEP(H, a, b, c, d, e, words[55], 0x8f1bbcdc);
STEP(H, a, b, c, d, e, words[56], 0x8f1bbcdc);
STEP(H, a, b, c, d, e, words[57], 0x8f1bbcdc);
STEP(H, a, b, c, d, e, words[58], 0x8f1bbcdc);
STEP(H, a, b, c, d, e, words[59], 0x8f1bbcdc);
STEP(I, a, b, c, d, e, words[60], 0xca62c1d6);
STEP(I, a, b, c, d, e, words[61], 0xca62c1d6);
STEP(I, a, b, c, d, e, words[62], 0xca62c1d6);
STEP(I, a, b, c, d, e, words[63], 0xca62c1d6);
STEP(I, a, b, c, d, e, words[64], 0xca62c1d6);
STEP(I, a, b, c, d, e, words[65], 0xca62c1d6);
STEP(I, a, b, c, d, e, words[66], 0xca62c1d6);
STEP(I, a, b, c, d, e, words[67], 0xca62c1d6);
STEP(I, a, b, c, d, e, words[68], 0xca62c1d6);
STEP(I, a, b, c, d, e, words[69], 0xca62c1d6);
STEP(I, a, b, c, d, e, words[70], 0xca62c1d6);
STEP(I, a, b, c, d, e, words[71], 0xca62c1d6);
STEP(I, a, b, c, d, e, words[72], 0xca62c1d6);
STEP(I, a, b, c, d, e, words[73], 0xca62c1d6);
STEP(I, a, b, c, d, e, words[74], 0xca62c1d6);
STEP(I, a, b, c, d, e, words[75], 0xca62c1d6);
STEP(I, a, b, c, d, e, words[76], 0xca62c1d6);
STEP(I, a, b, c, d, e, words[77], 0xca62c1d6);
STEP(I, a, b, c, d, e, words[78], 0xca62c1d6);
STEP(I, a, b, c, d, e, words[79], 0xca62c1d6);
a += oa, b += ob, c += oc, d += od, e += oe;
p += 64;
} while (size -= 64);
ctx->a = a, ctx->b = b, ctx->c = c, ctx->d = d, ctx->e = e;
return p;
}
static void sha1_init(sha1_t *ctx) {
ctx->a = 0x67452301;
ctx->b = 0xefcdab89;
ctx->c = 0x98badcfe;
ctx->d = 0x10325476;
ctx->e = 0xc3d2e1f0;
ctx->bytes = 0;
}
static void sha1_update(sha1_t *ctx, const void *data, size_t size) {
size_t used = ctx->bytes & 0x3f;
ctx->bytes += size;
if (used) {
size_t free = 64 - used;
if (size < free) {
memcpy(&ctx->buffer[used], data, size);
return;
}
memcpy(&ctx->buffer[used], data, free);
data = (uint8_t*)data + free;
size -= free;
sha1_body(ctx, ctx->buffer, 64);
}
if (size >= 64) {
data = sha1_body(ctx, data, size & ~(size_t)0x3f);
size &= 0x3f;
}
memcpy(ctx->buffer, data, size);
}
static void sha1_finish(sha1_t *ctx, uint8_t result[20]) {
size_t used = ctx->bytes & 0x3f;
size_t free = 64 - used - 1;
ctx->buffer[used++] = 0x80;
if (free < 8) {
memset(&ctx->buffer[used], 0, free);
sha1_body(ctx, ctx->buffer, 64);
used = 0, free = 64;
}
memset(&ctx->buffer[used], 0, free - 8);
ctx->bytes <<= 3;
DUMP(ctx->buffer, 14, ctx->bytes >> 32);
DUMP(ctx->buffer, 15, ctx->bytes );
sha1_body(ctx, ctx->buffer, 64);
DUMP(result, 0, ctx->a);
DUMP(result, 1, ctx->b);
DUMP(result, 2, ctx->c);
DUMP(result, 3, ctx->d);
DUMP(result, 4, ctx->e);
}
#define SHA1_TYPE "sha1.Object"
static void update(sha1_t *sha1, lua_State *L, int i, int top) {
for (; i <= top; ++i) {
size_t len;
const char *s = luaL_checklstring(L, i, &len);
sha1_update(sha1, s, len);
}
}
static int Lnew(lua_State *L) {
int top = lua_gettop(L);
sha1_t *sha1 = (sha1_t*)lua_newuserdata(L, sizeof(sha1_t));
sha1_init(sha1);
luaL_setmetatable(L, SHA1_TYPE);
update(sha1, L, 1, top);
return 1;
}
static int Lupdate(lua_State *L) {
sha1_t *sha1 = (sha1_t*)luaL_checkudata(L, 1, SHA1_TYPE);
update(sha1, L, 2, lua_gettop(L));
lua_settop(L, 1);
return 1;
}
static int Lfinish(lua_State *L) {
sha1_t *sha1 = (sha1_t*)luaL_checkudata(L, 1, SHA1_TYPE);
uint8_t result[20];
update(sha1, L, 2, lua_gettop(L));
sha1_finish(sha1, result);
sha1_init(sha1);
lua_pushlstring(L, (const char*)result, 20);
return 1;
}
static int push_hexa(lua_State *L, const char *s, size_t len) {
const char *hexa = "0123456789ABCDEF";
size_t i;
luaL_Buffer B;
luaL_buffinit(L, &B);
for (i = 0; i < len; ++i) {
char *p = luaL_prepbuffer(&B);
*p++ = hexa[(s[i] >> 4) & 0xF];
*p++ = hexa[(s[i] >> 0) & 0xF];
luaL_addsize(&B, 2);
}
luaL_pushresult(&B);
return 1;
}
static void sum(lua_State *L, uint8_t result[20]) {
sha1_t sha1;
sha1_init(&sha1);
update(&sha1, L, 1, lua_gettop(L));
sha1_finish(&sha1, result);
}
static int Lsum(lua_State *L) {
uint8_t result[20];
sum(L, result);
lua_pushlstring(L, (const char*)result, 20);
return 1;
}
static int Lsumhexa(lua_State *L) {
uint8_t result[20];
sum(L, result);
return push_hexa(L, (const char*)result, 20);
}
static int Ltohex(lua_State *L) {
size_t len;
const char *s = luaL_checklstring(L, 1, &len);
return push_hexa(L, s, len);
}
LUALIB_API int luaopen_sha1(lua_State *L) {
luaL_Reg libs[] = {
#define ENTRY(name) { #name, L##name }
ENTRY(new),
ENTRY(sum),
ENTRY(sumhexa),
ENTRY(tohex),
ENTRY(update),
ENTRY(finish),
#undef ENTRY
{ NULL, NULL }
};
if (luaL_newmetatable(L, SHA1_TYPE)) {
luaL_setfuncs(L, libs, 0);
lua_pushvalue(L, -1);
lua_setfield(L, -2, "__index");
}
return 1;
}
/* cc: flags+='-O3 -ggdb -pedantic -std=c90 -Wall -Wextra --coverage'
* maccc: flags+='-shared -undefined dynamic_lookup' output='sha1.so'
* win32cc: flags+='-s -mdll -DLUA_BUILD_AS_DLL ' output='sha1.dll' libs+='-llua53' */
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment