hare

[hare] The Hare programming language
git clone https://git.torresjrjr.com/hare.git
Log | Files | Refs | README | LICENSE

adler32.ha (2145B)


      1 // SPDX-License-Identifier: MPL-2.0
      2 // (c) Hare authors <https://harelang.org>
      3 
      4 use endian;
      5 use hash;
      6 use io;
      7 use strings;
      8 
      9 // The size, in bytes, of an Adler-32 checksum.
     10 export def SZ: size = 4;
     11 
     12 export type state = struct {
     13 	hash::hash,
     14 	a: u32,
     15 	b: u32,
     16 };
     17 
     18 const adler32_vtable: io::vtable = io::vtable {
     19 	writer = &write,
     20 	...
     21 };
     22 
     23 // Creates a [[hash::hash]] which computes the Adler-32 checksum algorithm. This
     24 // hash does not allocate any state, so you do not need to call [[hash::close]]
     25 // when you are done with it.
     26 export fn adler32() state = state {
     27 	stream = &adler32_vtable,
     28 	sum = &sum,
     29 	reset = &reset,
     30 	sz = 4,
     31 	a = 1,
     32 	b = 0,
     33 	...
     34 };
     35 
     36 fn write(s: *io::stream, buf: const []u8) (size | io::error) = {
     37 	let s = s: *state;
     38 	for (let i = 0z; i < len(buf); i += 1) {
     39 		s.a = (s.a + buf[i]) % 65521;
     40 		s.b = (s.b + s.a) % 65521;
     41 	};
     42 	return len(buf);
     43 };
     44 
     45 fn reset(h: *hash::hash) void = {
     46 	let h = h: *state;
     47 	h.a = 1;
     48 	h.b = 0;
     49 };
     50 
     51 fn sum(h: *hash::hash, buf: []u8) void = {
     52 	let h = h: *state;
     53 	// RFC 1950 specifies that Adler-32 checksums are stored in network
     54 	// order.
     55 	endian::beputu32(buf, (h.b << 16) | h.a);
     56 };
     57 
     58 export fn sum32(h: *hash::hash) u32 = {
     59 	assert(h.reset == &reset);
     60 	let h = h: *state;
     61 	return h.b << 16 | h.a;
     62 };
     63 
     64 @test fn adler32() void = {
     65 	const vectors: [](str, u32) = [
     66 		("", 1),
     67 		("hello world", 436929629),
     68 		("Hare is a cool language", 1578567727),
     69 		("'UNIX was not designed to stop its users from doing stupid things, as that would also stop them from doing clever things' - Doug Gwyn", 2140876731),
     70 		("'Life is too short to run proprietary software' - Bdale Garbee", 3135706652),
     71 		("'The central enemy of reliability is complexity.' - Geer et al", 3170309588),
     72 		("'A language that doesn’t have everything is actually easier to program in than some that do.' - Dennis Ritchie", 1148528899),
     73 
     74 	];
     75 
     76 	let hash = adler32();
     77 	let s: [4]u8 = [0...];
     78 
     79 	for (let i = 0z; i < len(vectors); i += 1) {
     80 		let vec = vectors[i];
     81 		hash::reset(&hash);
     82 		hash::write(&hash, strings::toutf8(vec.0));
     83 
     84 		hash::sum(&hash, s);
     85 
     86 		assert(endian::begetu32(s) == vec.1);
     87 		assert(sum32(&hash) == vec.1);
     88 	};
     89 };