Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Adding initial set of files

  • Loading branch information...
commit 1e9571b4436fa3f4c6a87c6d289565dc77211f8d 1 parent fb6d979
@Wiladams authored
View
176 BitBang.lua
@@ -0,0 +1,176 @@
+local ffi = require "ffi"
+
+local bit = require "bit"
+local band = bit.band
+local bor = bit.bor
+local bxor = bit.bxor
+local rshift = bit.rshift
+
+ffi.cdef[[
+typedef union {
+ uint8_t Byte;
+ int16_t Short;
+ uint16_t UShort;
+ int32_t Int32;
+ uint32_t UInt32;
+ int64_t Int64;
+ uint64_t UInt64;
+ float f;
+ double d;
+ uint8_t bytes[8];
+} bittypes_t
+]]
+bittypes = ffi.typeof("bittypes_t")
+
+function isset(value, bit)
+ return band(value, 2^bit) > 0
+end
+
+function setbit(value, bit)
+ return bor(value, 2^bit)
+end
+
+function clearbit(value, bit)
+ return bxor(value, 2^bit)
+end
+
+function numbertobinary(value, nbits, bigendian)
+ nbits = nbits or 32
+ local res={}
+
+ if bigendian then
+ for i=nbits-1,0,-1 do
+ if isset(value,i) then
+ table.insert(res, '1')
+ else
+ table.insert(res, '0')
+ end
+ end
+ else
+ for i=0, nbits-1 do
+ if isset(value,i) then
+ table.insert(res, '1')
+ else
+ table.insert(res, '0')
+ end
+ end
+ end
+
+ return table.concat(res)
+end
+
+
+
+function binarytonumber(str, bigendian)
+ local len = string.len(str)
+ local value = 0
+
+ if bigendian then
+ for i=0,len-1 do
+ if str:sub(len-i,len-i) == '1' then
+ value = setbit(value, i)
+ end
+ end
+ else
+ for i=0, len-1 do
+ if str:sub(i+1,i+1) == '1' then
+ value = setbit(value, i)
+ end
+ end
+ end
+
+ return value
+end
+
+function bytestobinary(bytes, length, offset, bigendian)
+ offset = offset or 0
+ nbits = 8
+
+ local res={}
+
+ if bigendian then
+ for offset=length-1, 0,-1 do
+ table.insert(res, numbertobinary(bytes[offset],nbits, bigendian))
+ end
+
+ else
+ for offset=0,length-1 do
+ table.insert(res, numbertobinary(bytes[offset],nbits, bigendian))
+ end
+ end
+
+ return table.concat(res)
+end
+
+function getbitsvalue(src, lowbit, bitcount)
+ lowbit = lowbit or 0
+ bitcount = bitcount or 32
+
+ local value = 0
+ for i=0,bitcount-1 do
+ value = bor(value, band(src, 2^(lowbit+i)))
+ end
+
+ return rshift(value,lowbit)
+end
+
+function getbitstring(value, lowbit, bitcount)
+ return numbertobinary(getbitsvalue(value, lowbit, bitcount))
+end
+
+-- Given a bit number, calculate which byte
+-- it would be in, and which bit within that
+-- byte.
+function getbitbyteoffset(bitnumber)
+ local byteoffset = math.floor(bitnumber /8)
+ local bitoffset = bitnumber % 8
+
+ return byteoffset, bitoffset
+end
+
+
+function getbitsfrombytes(bytes, startbit, bitcount)
+ if not bytes then return nil end
+
+ local value = 0
+
+ for i=1,bitcount do
+ local byteoffset, bitoffset = getbitbyteoffset(startbit+i-1)
+ local bitval = isset(bytes[byteoffset], bitoffset)
+--print(byteoffset, bitoffset, bitval);
+ if bitval then
+ value = setbit(value, i-1);
+ end
+ end
+
+ return value
+end
+
+function setbitstobytes(bytes, startbit, bitcount, value, bigendian)
+
+ local byteoffset=0;
+ local bitoffset=0;
+ local bitval = false
+
+ if bigendian then
+ for i=0,bitcount-1 do
+ byteoffset, bitoffset = getbitbyteoffset(startbit+i)
+ bitval = isset(value, i)
+ if bitval then
+ bytes[byteoffset] = setbit(bytes[byteoffset], bitoffset);
+ end
+ end
+ else
+ for i=0,bitcount-1 do
+ byteoffset, bitoffset = getbitbyteoffset(startbit+i)
+ bitval = isset(value, i)
+ if bitval then
+ bytes[byteoffset] = setbit(bytes[byteoffset], bitoffset);
+ end
+ end
+ end
+
+ return bytes
+end
+
+
View
237 MD5.lua
@@ -0,0 +1,237 @@
+
+local ffi = require "ffi"
+local bit = require "bit"
+local bxor = bit.bxor
+local bnot = bit.bnot
+local band = bit.band
+local bor = bit.bor
+local rshift = bit.rshift
+local lshift = bit.lshift
+
+require "memutils"
+require "stringzutils"
+
+ffi.cdef[[
+typedef struct MD5Context {
+ uint32_t buf[4];
+ uint32_t bits[2];
+ unsigned char input[64];
+} MD5_CTX;
+]]
+MD5_CTX = ffi.typeof("MD5_CTX");
+
+
+function byteReverse(buf, len)
+end
+
+function F1(x, y, z)
+ return bxor(z, band(x, bxor(y, z)))
+end
+
+function F2(x, y, z) return F1(z, x, y) end
+
+function F3(x, y, z) return bxor(x, y, z) end
+function F4(x, y, z) return bxor(y, bor(x, bnot(z))) end
+
+function MD5STEP(f, w, x, y, z, data, s)
+ w = w + f(x, y, z) + data;
+ w = bor(lshift(w,s), rshift(w,(32-s)))
+ w = w + x;
+
+ return w;
+end
+
+function printmd5ctx(ctx)
+ for i=0,3 do
+ print(string.format("ctx.buf[%d]: 0x%x", i, ctx.buf[i]));
+ end
+
+ print(string.format("ctx.bits[0]: %d", ctx.bits[0]));
+ print(string.format("ctx.bits[1]: %d", ctx.bits[1]));
+end
+
+-- Start MD5 accumulation. Set bit count to 0 and buffer to mysterious
+-- initialization constants.
+function MD5Init(ctx)
+ ctx.buf[0] = 0x67452301;
+ ctx.buf[1] = 0xefcdab89;
+ ctx.buf[2] = 0x98badcfe;
+ ctx.buf[3] = 0x10325476;
+
+ ctx.bits[0] = 0;
+ ctx.bits[1] = 0;
+end
+
+function MD5Transform(buf, input)
+ local a = buf[0];
+ local b = buf[1];
+ local c = buf[2];
+ local d = buf[3];
+
+ a = MD5STEP(F1, a, b, c, d, input[0] + 0xd76aa478, 7);
+ d = MD5STEP(F1, d, a, b, c, input[1] + 0xe8c7b756, 12);
+ c = MD5STEP(F1, c, d, a, b, input[2] + 0x242070db, 17);
+ b = MD5STEP(F1, b, c, d, a, input[3] + 0xc1bdceee, 22);
+ a = MD5STEP(F1, a, b, c, d, input[4] + 0xf57c0faf, 7);
+ d = MD5STEP(F1, d, a, b, c, input[5] + 0x4787c62a, 12);
+ c = MD5STEP(F1, c, d, a, b, input[6] + 0xa8304613, 17);
+ b = MD5STEP(F1, b, c, d, a, input[7] + 0xfd469501, 22);
+ a = MD5STEP(F1, a, b, c, d, input[8] + 0x698098d8, 7);
+ d = MD5STEP(F1, d, a, b, c, input[9] + 0x8b44f7af, 12);
+ c = MD5STEP(F1, c, d, a, b, input[10] + 0xffff5bb1, 17);
+ b = MD5STEP(F1, b, c, d, a, input[11] + 0x895cd7be, 22);
+ a = MD5STEP(F1, a, b, c, d, input[12] + 0x6b901122, 7);
+ d = MD5STEP(F1, d, a, b, c, input[13] + 0xfd987193, 12);
+ c = MD5STEP(F1, c, d, a, b, input[14] + 0xa679438e, 17);
+ b = MD5STEP(F1, b, c, d, a, input[15] + 0x49b40821, 22);
+
+ a = MD5STEP(F2, a, b, c, d, input[1] + 0xf61e2562, 5);
+ d = MD5STEP(F2, d, a, b, c, input[6] + 0xc040b340, 9);
+ c = MD5STEP(F2, c, d, a, b, input[11] + 0x265e5a51, 14);
+ b = MD5STEP(F2, b, c, d, a, input[0] + 0xe9b6c7aa, 20);
+ a = MD5STEP(F2, a, b, c, d, input[5] + 0xd62f105d, 5);
+ d = MD5STEP(F2, d, a, b, c, input[10] + 0x02441453, 9);
+ c = MD5STEP(F2, c, d, a, b, input[15] + 0xd8a1e681, 14);
+ b = MD5STEP(F2, b, c, d, a, input[4] + 0xe7d3fbc8, 20);
+ a = MD5STEP(F2, a, b, c, d, input[9] + 0x21e1cde6, 5);
+ d = MD5STEP(F2, d, a, b, c, input[14] + 0xc33707d6, 9);
+ c = MD5STEP(F2, c, d, a, b, input[3] + 0xf4d50d87, 14);
+ b = MD5STEP(F2, b, c, d, a, input[8] + 0x455a14ed, 20);
+ a = MD5STEP(F2, a, b, c, d, input[13] + 0xa9e3e905, 5);
+ d = MD5STEP(F2, d, a, b, c, input[2] + 0xfcefa3f8, 9);
+ c = MD5STEP(F2, c, d, a, b, input[7] + 0x676f02d9, 14);
+ b = MD5STEP(F2, b, c, d, a, input[12] + 0x8d2a4c8a, 20);
+
+ a = MD5STEP(F3, a, b, c, d, input[5] + 0xfffa3942, 4);
+ d = MD5STEP(F3, d, a, b, c, input[8] + 0x8771f681, 11);
+ c = MD5STEP(F3, c, d, a, b, input[11] + 0x6d9d6122, 16);
+ b = MD5STEP(F3, b, c, d, a, input[14] + 0xfde5380c, 23);
+ a = MD5STEP(F3, a, b, c, d, input[1] + 0xa4beea44, 4);
+ d = MD5STEP(F3, d, a, b, c, input[4] + 0x4bdecfa9, 11);
+ c = MD5STEP(F3, c, d, a, b, input[7] + 0xf6bb4b60, 16);
+ b = MD5STEP(F3, b, c, d, a, input[10] + 0xbebfbc70, 23);
+ a = MD5STEP(F3, a, b, c, d, input[13] + 0x289b7ec6, 4);
+ d = MD5STEP(F3, d, a, b, c, input[0] + 0xeaa127fa, 11);
+ c = MD5STEP(F3, c, d, a, b, input[3] + 0xd4ef3085, 16);
+ b = MD5STEP(F3, b, c, d, a, input[6] + 0x04881d05, 23);
+ a = MD5STEP(F3, a, b, c, d, input[9] + 0xd9d4d039, 4);
+ d = MD5STEP(F3, d, a, b, c, input[12] + 0xe6db99e5, 11);
+ c = MD5STEP(F3, c, d, a, b, input[15] + 0x1fa27cf8, 16);
+ b = MD5STEP(F3, b, c, d, a, input[2] + 0xc4ac5665, 23);
+
+ a = MD5STEP(F4, a, b, c, d, input[0] + 0xf4292244, 6);
+ d = MD5STEP(F4, d, a, b, c, input[7] + 0x432aff97, 10);
+ c = MD5STEP(F4, c, d, a, b, input[14] + 0xab9423a7, 15);
+ b = MD5STEP(F4, b, c, d, a, input[5] + 0xfc93a039, 21);
+ a = MD5STEP(F4, a, b, c, d, input[12] + 0x655b59c3, 6);
+ d = MD5STEP(F4, d, a, b, c, input[3] + 0x8f0ccc92, 10);
+ c = MD5STEP(F4, c, d, a, b, input[10] + 0xffeff47d, 15);
+ b = MD5STEP(F4, b, c, d, a, input[1] + 0x85845dd1, 21);
+ a = MD5STEP(F4, a, b, c, d, input[8] + 0x6fa87e4f, 6);
+ d = MD5STEP(F4, d, a, b, c, input[15] + 0xfe2ce6e0, 10);
+ c = MD5STEP(F4, c, d, a, b, input[6] + 0xa3014314, 15);
+ b = MD5STEP(F4, b, c, d, a, input[13] + 0x4e0811a1, 21);
+ a = MD5STEP(F4, a, b, c, d, input[4] + 0xf7537e82, 6);
+ d = MD5STEP(F4, d, a, b, c, input[11] + 0xbd3af235, 10);
+ c = MD5STEP(F4, c, d, a, b, input[2] + 0x2ad7d2bb, 15);
+ b = MD5STEP(F4, b, c, d, a, input[9] + 0xeb86d391, 21);
+
+ buf[0] = buf[0] + a;
+ buf[1] = buf[1] + b;
+ buf[2] = buf[2] + c;
+ buf[3] = buf[3] + d;
+end
+
+function MD5Update(ctx, buf, len)
+ local t;
+
+ t = ctx.bits[0];
+ ctx.bits[0] = t + lshift( len, 3)
+ if (ctx.bits[0] < t) then
+ ctx.bits[1] = ctx.bits[1] + 1;
+ end
+
+ ctx.bits[1] = ctx.bits[1] + rshift(len, 29);
+
+ t = band(rshift(t, 3), 0x3f);
+
+ if (t > 0) then
+ p = ffi.cast("unsigned char *", ctx.input + t);
+
+ t = 64 - t;
+ if (len < t) then
+ memcpy(p, buf, len);
+ return;
+ end
+
+ memcpy(p, buf, t);
+ byteReverse(ctx.input, 16);
+ MD5Transform(ctx.buf, ffi.cast("uint32_t *", ctx.input));
+ buf = buf + t;
+ len = len - t;
+ end
+
+ while (len >= 64) do
+ memcpy(ctx.input, buf, 64);
+ byteReverse(ctx.input, 16);
+ MD5Transform(ctx.buf, ffi.cast("uint32_t *", ctx.input));
+ buf = buf + 64;
+ len = len - 64;
+ end
+
+ memcpy(ctx.input, buf, len);
+end
+
+function MD5Final(digest, ctx)
+
+ local count;
+ local p;
+
+ count = band(rshift(ctx.bits[0], 3), 0x3F);
+
+ p = ctx.input + count;
+ p[0] = 0x80;
+ p = p + 1;
+ count = 64 - 1 - count;
+
+ if (count < 8) then
+ memset(p, 0, count);
+ byteReverse(ctx.input, 16);
+ MD5Transform(ctx.buf, ffi.cast("uint32_t *", ctx.input));
+ memset(ctx.input, 0, 56);
+ else
+ memset(p, 0, count - 8);
+ end
+
+ byteReverse(ctx.input, 14);
+
+ ffi.cast("uint32_t *", ctx.input)[14] = ctx.bits[0];
+ ffi.cast("uint32_t *", ctx.input)[15] = ctx.bits[1];
+
+ MD5Transform(ctx.buf, ffi.cast("uint32_t *", ctx.input));
+ byteReverse(ffi.cast("unsigned char *",ctx.buf), 4);
+ memcpy(digest, ctx.buf, 16);
+ memset(ffi.cast("char *", ctx), 0, ffi.sizeof(ctx));
+end
+
+
+function md5(luastr)
+ local buf = ffi.new("char[33]");
+ local hash = ffi.new("uint8_t[16]");
+ local len = string.len(luastr)
+ local p = ffi.cast("char *", luastr);
+
+ local ctx = MD5_CTX();
+
+ MD5Init(ctx);
+
+ MD5Update(ctx, p, len);
+ MD5Final(hash, ctx);
+ bin2str(buf, hash, ffi.sizeof(hash));
+
+ return ffi.string(buf);
+end
+
+
+
+
View
26 README.md
@@ -1,4 +1,28 @@
LAPHLibs
========
-Lua Application Programming Helper Libraries
+Lua Application Programming Helper Libraries
+
+This is a repository of things I have found to be useful
+while programming in LuaJIT. In particular, there are
+a number of functions that are useful when you're programming
+using the FFI.
+
+BitBang.lua - Lowest level bit twiddling. Builds upon the bitops
+allowing the getting/setting of bit values within a larger
+array of values.
+
+MD5.lua - Implementation of the MD5 hash algorithm
+
+memutils.lua - contains several routines that have
+C equivalents, such as memset, memcpy, memcmp, memchr, memmove.
+Also contains a few convenience functions related to dealing
+with chunks of memory.
+
+stringzutils.lua - Contains a set of functions that deal with
+null terminated strings. All the typical security hole opening
+functions such as strcpy, strcmp are there, as well as their
+marginally more secure counterparts such as strlcpy, and strlcat.
+
+
+
View
124 memutils.lua
@@ -0,0 +1,124 @@
+local ffi = require "ffi"
+local bit = require "bit"
+local band = bit.band
+local bor = bit.bor
+local rshift = bit.rshift
+local lshift = bit.lshift
+
+--[[
+ binary functions
+
+ ARRAY_SIZE
+ NewStruct
+ isbyte
+ bzero
+ bcopy
+ bcmp
+--]]
+
+function ARRAY_SIZE(array)
+ local typestr = tostring(ffi.typeof(array))
+
+ --local elemtype, nelem = string.match(typestr, "ctype<(%w+)%s+%[(%d+)%]>")
+ local nelem = string.match(typestr, "(%d+)")
+
+ return tonumber(nelem)
+end
+
+
+function NewStruct(structname)
+ if not cast then return nil end
+
+ local size = ffi.sizeof(structname)
+ return ffi.cast(structname,ffi.new("uint8_t["..size.."]"));
+end
+
+
+function isbyte(n)
+ return band(n,0xff) == n
+end
+
+function bzero(dest, nbytes)
+ ffi.fill(dest, nbytes)
+ return dest
+end
+
+function bcopy(src, dest, nbytes)
+ ffi.copy(dest, src, nbytes)
+end
+
+function bcmp(ptr1, ptr2, nbytes)
+ for i=0,nbytes do
+ if ptr1[i] ~= ptr2[i] then return -1 end
+ end
+
+ return 0
+end
+
+--[[
+ Memory functions
+
+ memchr(const void *buf, int val, size_t maxCount);
+ memcmp(const void *buf1, const void *buf2, size_t size);
+ memcpy_s(void *dst, int dstSize, const void *src, size_t maxCount)
+ memset(void * dst, int val, size_t size)
+--]]
+
+function memset(dest, c, len)
+ ffi.fill(dest, len, c)
+ return dest
+end
+
+function memcpy(dest, src, nbytes)
+ ffi.copy(dest, src, nbytes)
+end
+
+function memcmp(ptr1, ptr2, nbytes)
+ local p1 = ffi.cast("uint8_t *", ptr1)
+ local p2 = ffi.cast("uint8_t *", ptr2)
+
+ for i=0,nbytes do
+ if p1[i] ~= p2[i] then return -1 end
+ end
+
+ return 0
+end
+
+function memchr(ptr, value, num)
+ ptr = ffi.cast("uint8_t *", ptr)
+ for i=0,num-1 do
+ if ptr[i] == value then return ptr+i end
+ end
+
+ return nil
+end
+
+function memmove(dst, src, num)
+ local srcptr = ffi.cast("uint8_t*", src)
+
+ -- If equal, just return
+ if dst == srcptr then return dst end
+
+
+ if srcptr < dst then
+ -- copy from end
+ for i=num-1,0, -1 do
+ dst[i] = srcptr[i];
+ end
+ else
+ -- copy from beginning
+ for i=0,num-1 do
+ dst[i] = srcptr[i];
+ end
+ end
+ return dst
+end
+
+
+
+
+
+
+
+
+
View
266 stringzutils.lua
@@ -0,0 +1,266 @@
+local ffi = require "ffi"
+local bit = require "bit"
+local band = bit.band
+local bor = bit.bor
+local rshift = bit.rshift
+local lshift = bit.lshift
+
+--[[
+ String Functions
+
+ strlen
+ strndup
+ strdup
+ strcpy
+ strlcpy
+ strlcat
+
+ strchr
+ strcmp
+ strncmp
+ strcasecmp
+ strncasecmp
+
+ strrchr
+ strstr
+
+ strpbrk
+
+ bin2str
+--]]
+
+
+
+function strcmp(s1, s2)
+ local s1ptr = ffi.cast("uint8_t *", s1);
+ local s2ptr = ffi.cast("uint8_t *", s2);
+
+ -- uint8_t
+ local uc1;
+ local uc2;
+
+ -- Move s1 and s2 to the first differing characters
+ -- in each string, or the ends of the strings if they
+ -- are identical.
+ while (s1ptr[0] ~= 0 and s1ptr[0] == s2ptr[0]) do
+ s1ptr = s1ptr + 1
+ s2ptr = s2ptr + 1
+ end
+
+ -- Compare the characters as unsigned char and
+ -- return the difference.
+ uc1 = s1ptr[0];
+ uc2 = s2ptr[0];
+
+ if (uc1 < uc2) then
+ return -1
+ elseif (uc1 > uc2) then
+ return 1
+ end
+
+ return 0
+end
+
+
+function strncmp(str1, str2, num)
+ local ptr1 = ffi.cast("uint8_t*", str1)
+ local ptr2 = ffi.cast("uint8_t*", str2)
+
+ for i=0,num-1 do
+ if str1[i] == 0 or str2[i] == 0 then return 0 end
+
+ if ptr1[i] > ptr2[i] then return 1 end
+ if ptr1[i] < ptr2[i] then return -1 end
+ end
+
+ return 0
+end
+
+function strncasecmp(str1, str2, num)
+ local ptr1 = ffi.cast("uint8_t*", str1)
+ local ptr2 = ffi.cast("uint8_t*", str2)
+
+ for i=0,num-1 do
+ if str1[i] == 0 or str2[i] == 0 then return 0 end
+
+ if ptr1[i] > ptr2[i] then return 1 end
+ if ptr1[i] < ptr2[i] then return -1 end
+ end
+
+ return 0
+end
+
+
+function strcasecmp(str1, str2)
+ local ptr1 = ffi.cast("uint8_t*", str1)
+ local ptr2 = ffi.cast("uint8_t*", str2)
+
+ local num = math.min(strlen(ptr1), strlen(ptr2))
+ for i=0,num-1 do
+ if str1[i] == 0 or str2[i] == 0 then return 0 end
+
+ if ptr1[i] > ptr2[i] then return 1 end
+ if ptr1[i] < ptr2[i] then return -1 end
+ end
+
+ return 0
+end
+
+function strlen(str)
+ local idx = 0
+ while str[idx] ~= 0 do
+ idx = idx + 1
+ end
+
+ return idx
+end
+
+function strndup(str,n)
+ local len = strlen(str)
+ local len = math.min(n,len)
+
+ local newstr = ffi.new("char["..(len+1).."]");
+ ffi.copy(newstr, str, len)
+ newstr[len] = 0
+
+ return newstr
+end
+
+function strdup(str)
+ str = ffi.cast("char *", str)
+ local len = strlen(str)
+
+ local newstr = ffi.new("char["..(len+1).."]");
+ ffi.copy(newstr, str, len)
+ newstr[len] = 0
+
+ return newstr
+end
+
+function strcpy(dst, src)
+ local dstptr = ffi.cast("char *", dst)
+ local srcptr = ffi.cast("char *", src)
+
+ -- Do the copying in a loop.
+ while (dstptr[0] ~= 0 and srcptr[0] ~= 0) do
+ dstptr[0] = srcptr[0];
+ dstptr = dstptr + 1;
+ srcptr = srcptr + 1;
+ end
+
+ -- Return the destination string.
+ return dst;
+end
+
+function strlcpy(dst, src, size)
+ local dstptr = ffi.cast("char *", dst)
+ local srcptr = ffi.cast("char *", src)
+
+ local len = strlen(src)
+ local len = math.min(size-1,len)
+
+ ffi.copy(dstptr, srcptr, len)
+ dstptr[len] = 0
+
+ return len
+end
+
+function strlcat(dst, src, size)
+
+ local dstptr = ffi.cast("char *", dst)
+ local srcptr = ffi.cast("char *", src)
+
+ local dstlen = strlen(dstptr);
+ local dstremaining = size-dstlen-1
+ local srclen = strlen(srcptr);
+ local len = math.min(dstremaining, srclen)
+
+
+ for idx=dstlen,dstlen+len do
+ dstptr[idx] = srcptr[idx-dstlen];
+ end
+
+ return dstlen+len
+end
+
+
+
+function strchr(s, c)
+ while s[0] ~= c do
+ if s[0] == 0 then
+ return nil
+ end
+ s = s + 1;
+ end
+
+ return s
+end
+
+
+function strstr(str, target)
+
+ if (target == nil or target[0] == 0) then
+ return str;
+ end
+
+ local p1 = str;
+
+ while (p1[0] ~= 0) do
+
+ local p1Begin = p1;
+ local p2 = target;
+
+ while (p1[0]~=0 and p2[0]~=0 and p1[0] == p2[0]) do
+ p1 = p1 + 1;
+ p2 = p2 + 1;
+ end
+
+ if (p2[0] == 0) then
+ return p1Begin;
+ end
+
+ p1 = p1Begin + 1;
+ end
+
+ return nil;
+end
+
+
+--[[
+ String Helpers
+--]]
+
+-- Given two null terminated strings
+function string_same(a, b)
+ local bytes = 0;
+
+ while (a[bytes] ~= 0 and b[bytes] ~= 0 and a[bytes] == b[bytes]) do
+ bytes = bytes+1
+ end
+
+ return bytes;
+end
+
+-- Stringify binary data. Output buffer must be twice as big as input,
+-- because each byte takes 2 bytes in string representation
+local hex = strdup("0123456789abcdef");
+
+function bin2str(to, p, len)
+--print("bin2str, len: ", len);
+ local off1, off2;
+ while (len > 0) do
+ off1 = rshift(p[0], 4)
+
+ to[0] = hex[off1];
+ to = to + 1;
+ off2 = band(p[0], 0x0f);
+ to[0] = hex[off2];
+ to = to + 1;
+ p = p + 1;
+ len = len - 1;
+
+-- print(off1, off2);
+ end
+ to[0] = 0;
+end
+
View
32 tests/test_md5.lua
@@ -0,0 +1,32 @@
+package.path = package.path..";..\\?.lua";
+
+local ffi = require "ffi"
+
+require "MD5"
+
+s0='message digest'
+s1='abcdefghijklmnopqrstuvwxyz'
+s2='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'
+s3='1234567890123456789012345678901234567890'
+ ..'1234567890123456789012345678901234567890'
+
+s4='Test vector from febooti.com'
+s5 = 'The quick brown fox jumps over the lazy dog'
+s6 = 'The quick brown fox jumps over the lazy dog.'
+
+ -- Test the simple digest form
+ -- http://tools.ietf.org/html/rfc1321
+
+assert(md5('') =='d41d8cd98f00b204e9800998ecf8427e')
+assert(md5('a') =='0cc175b9c0f1b6a831c399e269772661')
+assert(md5('abc') =='900150983cd24fb0d6963f7d28e17f72')
+assert(md5(s0) =='f96b697d7cb7938d525a2f31aaf161d0')
+assert(md5(s1) =='c3fcd3d76192e4007dfb496cca67e13b')
+assert(md5(s2) =='d174ab98d277d9f5a5611c2c9f419d9f')
+assert(md5(s3) =='57edf4a22be3c955ac49da2e2107b67a')
+assert(md5(s4) =='500ab6613c6db7fbd30c62f5ff573d0f')
+
+-- http://en.wikipedia.org/wiki/MD5
+assert(md5(s5) =='9e107d9d372bb6826bd81d3542a419d6')
+assert(md5(s6) =='e4d909c290d0fb1ca068ffaddf22cbd0')
+
View
86 tests/test_memutils.lua
@@ -0,0 +1,86 @@
+package.path = package.path..";..\\?.lua";
+
+local ffi = require "ffi"
+require "memutils"
+require "stringzutils"
+
+local str1 = strdup("william")
+local str2 = strdup("will")
+
+function printString(str)
+ print(ffi.string(str));
+end
+
+function test_strcmp()
+ printString(str1);
+ printString(str2);
+
+ print("0 : ", strcmp(str1, str1))
+ print("1 : ", strcmp(str1, str2))
+ print("-1 : ", strcmp(str2, str1))
+end
+
+
+
+function test_array_size()
+ local arr = ffi.new("char[255]")
+ print(ffi.sizeof(arr))
+
+ local str = strdup("William")
+ print("str: ", ffi.sizeof(str))
+
+ local typestr = tostring(ffi.typeof(str))
+ --print("match: ", typestr, string.match(typestr, "ctype<%w [%d+]>"))
+ print("match: ", string.match(typestr, "ctype<(%w+)%s+%[(%d+)%]>"))
+
+ local arr2 = ffi.new("int[256][10]")
+ typestr = tostring(ffi.typeof(arr2))
+ print("match: ", string.match(typestr, "ctype<(%w+)%s+%[(%d+)%]>"))
+
+ print("Array Size: ", ARRAY_SIZE(arr2));
+--print("ARRAY_SIZE: ", ARRAY_SIZE(str1));
+end
+
+function test_strchr()
+ local str = strdup("William");
+
+ local chr1 = strchr(str, string.byte('l'))
+ local chrnon = strchr(str, string.byte('c'))
+
+ print(charnon);
+ print(ffi.string(chr1))
+end
+
+function test_strstr()
+ local str = strdup("William");
+ local tar = strdup("ll");
+ local tar2 = strdup("cars");
+
+ local pos = strstr(str, tar)
+ print(ffi.string(pos));
+
+ pos = strstr(str, tar2)
+ print(pos);
+
+end
+
+function test_bin2str()
+ local p = strdup("William A Adams");
+ local to = ffi.new("char[256]");
+ local len = strlen(p);
+
+ bin2str(to, p, len)
+ local str = ffi.string(to)
+
+ print("str: ", str);
+end
+
+test_strcmp();
+
+test_array_size();
+
+test_strchr();
+
+test_strstr();
+
+test_bin2str();
Please sign in to comment.
Something went wrong with that request. Please try again.