Commit 197116ad authored by Jaromil's avatar Jaromil
Browse files

add hamming distance mearurement to octets

parent 2a5cccb3
......@@ -633,6 +633,43 @@ static int max(lua_State *L) {
}
static int popcount64b(uint64_t x) {
//types and constants
const uint64_t m1 = 0x5555555555555555; //binary: 0101...
const uint64_t m2 = 0x3333333333333333; //binary: 00110011..
const uint64_t m4 = 0x0f0f0f0f0f0f0f0f; //binary: 4 zeros, 4 ones ...
// const uint64_t m8 = 0x00ff00ff00ff00ff; //binary: 8 zeros, 8 ones ...
// const uint64_t m16 = 0x0000ffff0000ffff; //binary: 16 zeros, 16 ones ...
// const uint64_t m32 = 0x00000000ffffffff; //binary: 32 zeros, 32 ones
// const uint64_t hff = 0xffffffffffffffff; //binary: all ones
// const uint64_t h01 = 0x0101010101010101; //the sum of 256 to the power of 0,1,2,3...
x -= (x >> 1) & m1; //put count of each 2 bits into those 2 bits
x = (x & m2) + ((x >> 2) & m2); //put count of each 4 bits into those 4 bits
x = (x + (x >> 4)) & m4; //put count of each 8 bits into those 8 bits
x += x >> 8; //put count of each 16 bits into their lowest 8 bits
x += x >> 16; //put count of each 32 bits into their lowest 8 bits
x += x >> 32; //put count of each 64 bits into their lowest 8 bits
return x & 0x7f;
}
#define min(a, b) ((a) < (b) ? (a) : (b))
// compare bit by bit two arrays and returns the hamming distance
static int hamming_distance(lua_State *L) {
int distance, c, nlen;
octet *left = o_arg(L,1); SAFE(left);
octet *right = o_arg(L,2); SAFE(right);
nlen = min(left->len,right->len)>>3; // 64bit chunks of minimum length
// TODO: support sizes below 8byte length by padding
distance = 0;
uint64_t *l, *r;
l=(uint64_t*)left->val;
r=(uint64_t*)right->val;
for(c=0;c<nlen;c++)
distance += popcount64b( l[c] ^ r[c] );
lua_pushinteger(L,distance);
return 1;
}
int luaopen_octet(lua_State *L) {
const struct luaL_Reg octet_class[] = {
{"new", newoctet},
......@@ -648,6 +685,7 @@ int luaopen_octet(lua_State *L) {
{"str", from_string},
{"hex", from_hex},
{"bin", from_bin},
{"hamming", hamming_distance},
{NULL,NULL}
};
const struct luaL_Reg octet_methods[] = {
......@@ -662,6 +700,7 @@ int luaopen_octet(lua_State *L) {
{"pad", pad},
{"zero", zero},
{"max", max},
{"hamming", hamming_distance},
// idiomatic operators
{"__len",size},
{"__concat",concat_n},
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment