Last active
July 12, 2022 22:44
-
-
Save gfody/d6b0a917a7ce88fc0fe736ab31e08e37 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
create function imul(@a bigint, @b bigint) returns table as return | |
with | |
_0 as (select a = convert(binary(8), @a), b = convert(binary(8), @b)), | |
_1 as (select | |
hi_a = convert(bigint, substring(a, 1, 4)), lo_a = @a & 0xFFFFFFFF, | |
hi_b = convert(bigint, substring(b, 1, 4)), lo_b = @b & 0xFFFFFFFF from _0), | |
_2 as (select *, x = convert(binary(8), lo_a * lo_b) from _1), | |
_3 as (select s0 = substring(x, 5, 4), x = convert(bigint, substring(x, 1, 4)), hi_a, hi_b, lo_a, lo_b from _2), | |
_4 as (select x = (hi_a * lo_b + x) & 0xFFFFFFFF, s0, hi_b, lo_a from _3) | |
select value = convert(bigint, convert(binary(4), x + lo_a * hi_b) + s0) from _4 | |
create function fnv64(@s nvarchar(max)) returns table as return | |
with r(i, h) as ( | |
select 1, convert(bigint, -3750763034362895579) | |
union all | |
select i + 1, m.value from r | |
cross apply imul(r.h ^ unicode(substring(@s, i, 1)), 1099511628211) m | |
where i <= len(@s)) | |
select top 1 value = h from r order by i desc | |
select s, expected, actual = value from (values | |
('test1', 2271358237066212092), | |
('', -3750763034362895579), | |
(N'オーバーフロー', 5848856640766145455)) | |
x(s, expected) cross apply fnv64(s) | |
option (maxrecursion 0) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
challenge: implement FNV-1a in t-sql. there are no unsigned ints and overflows are not allowed, good luck!
output must match this reference function:
bonus: make it inlineable