Mercurial > prosody-hg
comparison spec/util_strbitop_spec.lua @ 13429:6cdc6923d65a
util.strbitop: Add common_prefix_bits() method
This returns the number of bits that two strings have in common. It is
significantly more efficient than similar calculations in Lua.
| author | Matthew Wild <mwild1@gmail.com> |
|---|---|
| date | Fri, 23 Feb 2024 12:08:37 +0000 |
| parents | 9677df320992 |
| children | 1a5e3cf037f6 |
comparison
equal
deleted
inserted
replaced
| 13428:dc1ad5f3f597 | 13429:6cdc6923d65a |
|---|---|
| 36 end); | 36 end); |
| 37 it("returns initial string if key is empty", function () | 37 it("returns initial string if key is empty", function () |
| 38 assert.equal("hello", strbitop.sxor("hello", "")); | 38 assert.equal("hello", strbitop.sxor("hello", "")); |
| 39 end); | 39 end); |
| 40 end); | 40 end); |
| 41 | |
| 42 describe("common_prefix_bits()", function () | |
| 43 local function B(s) | |
| 44 assert(#s%8==0, "Invalid test input: B(s): s should be a multiple of 8 bits in length"); | |
| 45 local byte = 0; | |
| 46 local out_str = {}; | |
| 47 for i = 1, #s do | |
| 48 local bit_ascii = s:byte(i); | |
| 49 if bit_ascii == 49 then -- '1' | |
| 50 byte = byte + 2^((7-(i-1))%8); | |
| 51 elseif bit_ascii ~= 48 then | |
| 52 error("Invalid test input: B(s): s should contain only '0' or '1' characters"); | |
| 53 end | |
| 54 if (i-1)%8 == 7 then | |
| 55 table.insert(out_str, string.char(byte)); | |
| 56 byte = 0; | |
| 57 end | |
| 58 end | |
| 59 return table.concat(out_str); | |
| 60 end | |
| 61 | |
| 62 local _cpb = strbitop.common_prefix_bits; | |
| 63 local function test(a, b) | |
| 64 local Ba, Bb = B(a), B(b); | |
| 65 local ret1 = _cpb(Ba, Bb); | |
| 66 local ret2 = _cpb(Bb, Ba); | |
| 67 assert(ret1 == ret2, ("parameter order should not make a difference to the result (%s, %s) = %d, reversed = %d"):format(a, b, ret1, ret2)); | |
| 68 return ret1; | |
| 69 end | |
| 70 local hex = require "util.hex"; | |
| 71 it("works on single bytes", function () | |
| 72 assert.equal(0, test("00000000", "11111111")); | |
| 73 assert.equal(1, test("10000000", "11111111")); | |
| 74 assert.equal(0, test("01000000", "11111111")); | |
| 75 assert.equal(0, test("01000000", "11111111")); | |
| 76 assert.equal(8, test("11111111", "11111111")); | |
| 77 end); | |
| 78 | |
| 79 it("works on multiple bytes", function () | |
| 80 for i = 0, 16 do | |
| 81 assert.equal(i, test(string.rep("1", i)..string.rep("0", 16-i), "1111111111111111")); | |
| 82 end | |
| 83 end); | |
| 84 end); | |
| 41 end); | 85 end); |
