| author | |
| committer | |
| log | 1c148f161905469b0ad5cf4de801cf287c491174 |
| tree | 702966068829d7775a33e79d734f24bca5eab97d |
| parent | 26d61812a8dbad204517d00d3a1f0e52275eceeb |
7 files changed, 61 insertions(+), 48 deletions(-)
lib/std/hash/adler.zig+7-1| ... | ... | @@ -3,7 +3,7 @@ |
| 3 | 3 | // https://tools.ietf.org/html/rfc1950#section-9 |
| 4 | 4 | // https://github.com/madler/zlib/blob/master/adler32.c |
| 5 | 5 | |
| 6 | const std = @import("../std.zig"); | |
| 6 | const std = @import("std"); | |
| 7 | 7 | const testing = std.testing; |
| 8 | 8 | |
| 9 | 9 | pub const Adler32 = struct { |
| ... | ... | @@ -126,3 +126,9 @@ test "adler32 very long with variation" { |
| 126 | 126 | |
| 127 | 127 | try testing.expectEqual(@as(u32, 0x5af38d6e), std.hash.Adler32.hash(long[0..])); |
| 128 | 128 | } |
| 129 | ||
| 130 | const verify = @import("verify.zig"); | |
| 131 | ||
| 132 | test "adler32 iterative" { | |
| 133 | try verify.iterativeApi(Adler32); | |
| 134 | } |
lib/std/hash/crc.zig+11-1| ... | ... | @@ -5,7 +5,7 @@ |
| 5 | 5 | // - Crc32SmallWithPoly uses only 64 bytes of memory but is slower. Be aware that this is |
| 6 | 6 | // still moderately fast just slow relative to the slicing approach. |
| 7 | 7 | |
| 8 | const std = @import("../std.zig"); | |
| 8 | const std = @import("std"); | |
| 9 | 9 | const builtin = @import("builtin"); |
| 10 | 10 | const debug = std.debug; |
| 11 | 11 | const testing = std.testing; |
| ... | ... | @@ -194,6 +194,8 @@ pub fn Crc32WithPoly(comptime poly: Polynomial) type { |
| 194 | 194 | }; |
| 195 | 195 | } |
| 196 | 196 | |
| 197 | const verify = @import("verify.zig"); | |
| 198 | ||
| 197 | 199 | test "crc32 ieee" { |
| 198 | 200 | const Crc32Ieee = Crc32WithPoly(.IEEE); |
| 199 | 201 | |
| ... | ... | @@ -210,6 +212,10 @@ test "crc32 castagnoli" { |
| 210 | 212 | try testing.expect(Crc32Castagnoli.hash("abc") == 0x364b3fb7); |
| 211 | 213 | } |
| 212 | 214 | |
| 215 | test "crc32 iterative" { | |
| 216 | try verify.iterativeApi(Crc32WithPoly(.IEEE)); | |
| 217 | } | |
| 218 | ||
| 213 | 219 | // half-byte lookup table implementation. |
| 214 | 220 | pub fn Crc32SmallWithPoly(comptime poly: Polynomial) type { |
| 215 | 221 | return struct { |
| ... | ... | @@ -258,6 +264,10 @@ pub fn Crc32SmallWithPoly(comptime poly: Polynomial) type { |
| 258 | 264 | }; |
| 259 | 265 | } |
| 260 | 266 | |
| 267 | test "small crc32 iterative" { | |
| 268 | try verify.iterativeApi(Crc32SmallWithPoly(.IEEE)); | |
| 269 | } | |
| 270 | ||
| 261 | 271 | test "small crc32 ieee" { |
| 262 | 272 | const Crc32Ieee = Crc32SmallWithPoly(.IEEE); |
| 263 | 273 |
lib/std/hash/crc/catalog_test.zig+1-1| ... | ... | @@ -1,6 +1,6 @@ |
| 1 | 1 | //! This file is auto-generated by tools/update_crc_catalog.zig. |
| 2 | 2 | |
| 3 | const std = @import("../../std.zig"); | |
| 3 | const std = @import("std"); | |
| 4 | 4 | const testing = std.testing; |
| 5 | 5 | const catalog = @import("catalog.zig"); |
| 6 | 6 |
lib/std/hash/fnv.zig+5| ... | ... | @@ -40,19 +40,24 @@ fn Fnv1a(comptime T: type, comptime prime: T, comptime offset: T) type { |
| 40 | 40 | }; |
| 41 | 41 | } |
| 42 | 42 | |
| 43 | const verify = @import("verify.zig"); | |
| 44 | ||
| 43 | 45 | test "fnv1a-32" { |
| 44 | 46 | try testing.expect(Fnv1a_32.hash("") == 0x811c9dc5); |
| 45 | 47 | try testing.expect(Fnv1a_32.hash("a") == 0xe40c292c); |
| 46 | 48 | try testing.expect(Fnv1a_32.hash("foobar") == 0xbf9cf968); |
| 49 | try verify.iterativeApi(Fnv1a_32); | |
| 47 | 50 | } |
| 48 | 51 | |
| 49 | 52 | test "fnv1a-64" { |
| 50 | 53 | try testing.expect(Fnv1a_64.hash("") == 0xcbf29ce484222325); |
| 51 | 54 | try testing.expect(Fnv1a_64.hash("a") == 0xaf63dc4c8601ec8c); |
| 52 | 55 | try testing.expect(Fnv1a_64.hash("foobar") == 0x85944171f73967e8); |
| 56 | try verify.iterativeApi(Fnv1a_64); | |
| 53 | 57 | } |
| 54 | 58 | |
| 55 | 59 | test "fnv1a-128" { |
| 56 | 60 | try testing.expect(Fnv1a_128.hash("") == 0x6c62272e07bb014262b821756295c58d); |
| 57 | 61 | try testing.expect(Fnv1a_128.hash("a") == 0xd228cb696f1a8caf78912b704e4a8964); |
| 62 | try verify.iterativeApi(Fnv1a_128); | |
| 58 | 63 | } |
lib/std/hash/verify.zig+27| ... | ... | @@ -13,6 +13,15 @@ fn hashMaybeSeed(comptime hash_fn: anytype, seed: anytype, buf: []const u8) @typ |
| 13 | 13 | } |
| 14 | 14 | } |
| 15 | 15 | |
| 16 | fn initMaybeSeed(comptime Hash: anytype, seed: anytype) Hash { | |
| 17 | const HashFn = @typeInfo(@TypeOf(Hash.init)).Fn; | |
| 18 | if (HashFn.params.len == 1) { | |
| 19 | return Hash.init(@intCast(seed)); | |
| 20 | } else { | |
| 21 | return Hash.init(); | |
| 22 | } | |
| 23 | } | |
| 24 | ||
| 16 | 25 | // Returns a verification code, the same as user by SMHasher. |
| 17 | 26 | // |
| 18 | 27 | // Hash keys of the form {0}, {0,1}, {0,1,2}... up to N=255, using 256-N as seed. |
| ... | ... | @@ -33,3 +42,21 @@ pub fn smhasher(comptime hash_fn: anytype) u32 { |
| 33 | 42 | |
| 34 | 43 | return @truncate(hashMaybeSeed(hash_fn, 0, buf_all[0..])); |
| 35 | 44 | } |
| 45 | ||
| 46 | pub fn iterativeApi(comptime Hash: anytype) !void { | |
| 47 | // Sum(1..32) = 528 | |
| 48 | var buf: [528]u8 = [_]u8{0} ** 528; | |
| 49 | var len: usize = 0; | |
| 50 | const seed = 0; | |
| 51 | ||
| 52 | var hasher = initMaybeSeed(Hash, seed); | |
| 53 | for (1..32) |i| { | |
| 54 | const r = hashMaybeSeed(Hash.hash, seed, buf[0 .. len + i]); | |
| 55 | hasher.update(buf[len..][0..i]); | |
| 56 | const f1 = hasher.final(); | |
| 57 | const f2 = hasher.final(); | |
| 58 | if (f1 != f2) return error.IterativeHashWasNotIdempotent; | |
| 59 | if (f1 != r) return error.IterativeHashDidNotMatchDirect; | |
| 60 | len += i; | |
| 61 | } | |
| 62 | } |
lib/std/hash/wyhash.zig+2-45| ... | ... | @@ -234,51 +234,8 @@ test "smhasher" { |
| 234 | 234 | try expectEqual(verify.smhasher(Wyhash.hash), 0xBD5E840C); |
| 235 | 235 | } |
| 236 | 236 | |
| 237 | test "test vectors streaming" { | |
| 238 | const step = 5; | |
| 239 | ||
| 240 | for (vectors) |e| { | |
| 241 | var wh = Wyhash.init(e.seed); | |
| 242 | var i: usize = 0; | |
| 243 | while (i < e.input.len) : (i += step) { | |
| 244 | const len = if (i + step > e.input.len) e.input.len - i else step; | |
| 245 | wh.update(e.input[i..][0..len]); | |
| 246 | } | |
| 247 | try expectEqual(e.expected, wh.final()); | |
| 248 | } | |
| 249 | } | |
| 250 | ||
| 251 | test "test ensure idempotent final call" { | |
| 252 | const e: TestVector = .{ .seed = 6, .expected = 0xc39cab13b115aad3, .input = "12345678901234567890123456789012345678901234567890123456789012345678901234567890" }; | |
| 253 | var wh = Wyhash.init(e.seed); | |
| 254 | wh.update(e.input); | |
| 255 | ||
| 256 | for (0..10) |_| { | |
| 257 | try expectEqual(e.expected, wh.final()); | |
| 258 | } | |
| 259 | } | |
| 260 | ||
| 261 | test "iterative non-divisible update" { | |
| 262 | var buf: [8192]u8 = undefined; | |
| 263 | for (&buf, 0..) |*e, i| { | |
| 264 | e.* = @as(u8, @truncate(i)); | |
| 265 | } | |
| 266 | ||
| 267 | const seed = 0x128dad08f; | |
| 268 | ||
| 269 | var end: usize = 32; | |
| 270 | while (end < buf.len) : (end += 32) { | |
| 271 | const non_iterative_hash = Wyhash.hash(seed, buf[0..end]); | |
| 272 | ||
| 273 | var wy = Wyhash.init(seed); | |
| 274 | var i: usize = 0; | |
| 275 | while (i < end) : (i += 33) { | |
| 276 | wy.update(buf[i..@min(i + 33, end)]); | |
| 277 | } | |
| 278 | const iterative_hash = wy.final(); | |
| 279 | ||
| 280 | try std.testing.expectEqual(iterative_hash, non_iterative_hash); | |
| 281 | } | |
| 237 | test "iterative api" { | |
| 238 | try verify.iterativeApi(Wyhash); | |
| 282 | 239 | } |
| 283 | 240 | |
| 284 | 241 | test "iterative maintains last sixteen" { |
lib/std/hash/xxhash.zig+8| ... | ... | @@ -461,6 +461,10 @@ test "xxhash64" { |
| 461 | 461 | try expectEqual(verify.smhasher(H.hash), 0x024B7CF4); |
| 462 | 462 | } |
| 463 | 463 | |
| 464 | test "xxhash64 iterative api" { | |
| 465 | try verify.iterativeApi(XxHash64); | |
| 466 | } | |
| 467 | ||
| 464 | 468 | test "xxhash32" { |
| 465 | 469 | const H = XxHash32; |
| 466 | 470 | |
| ... | ... | @@ -474,3 +478,7 @@ test "xxhash32" { |
| 474 | 478 | |
| 475 | 479 | try expectEqual(verify.smhasher(H.hash), 0xBA88B743); |
| 476 | 480 | } |
| 481 | ||
| 482 | test "xxhash32 iterative api" { | |
| 483 | try verify.iterativeApi(XxHash32); | |
| 484 | } |