@@ -10,6 +10,102 @@ const builtin = @import("builtin");
10
10
const debug = std .debug ;
11
11
const testing = std .testing ;
12
12
13
+ pub usingnamespace @import ("crc/catalog.zig" );
14
+
15
+ pub fn Algorithm (comptime W : type ) type {
16
+ return struct {
17
+ polynomial : W ,
18
+ initial : W ,
19
+ reflect_input : bool ,
20
+ reflect_output : bool ,
21
+ xor_output : W ,
22
+ };
23
+ }
24
+
25
+ pub fn Crc (comptime W : type , comptime algorithm : Algorithm (W )) type {
26
+ return struct {
27
+ const Self = @This ();
28
+ const I = if (@bitSizeOf (W ) < 8 ) u8 else W ;
29
+ const lookup_table = blk : {
30
+ @setEvalBranchQuota (2500 );
31
+
32
+ const poly = if (algorithm .reflect_input )
33
+ @bitReverse (@as (I , algorithm .polynomial )) >> (@bitSizeOf (I ) - @bitSizeOf (W ))
34
+ else
35
+ @as (I , algorithm .polynomial ) << (@bitSizeOf (I ) - @bitSizeOf (W ));
36
+
37
+ var table : [256 ]I = undefined ;
38
+ for (table ) | * e , i | {
39
+ var crc : I = i ;
40
+ if (algorithm .reflect_input ) {
41
+ var j : usize = 0 ;
42
+ while (j < 8 ) : (j += 1 ) {
43
+ crc = (crc >> 1 ) ^ ((crc & 1 ) * poly );
44
+ }
45
+ } else {
46
+ crc <<= @bitSizeOf (I ) - 8 ;
47
+ var j : usize = 0 ;
48
+ while (j < 8 ) : (j += 1 ) {
49
+ crc = (crc << 1 ) ^ (((crc >> (@bitSizeOf (I ) - 1 )) & 1 ) * poly );
50
+ }
51
+ }
52
+ e .* = crc ;
53
+ }
54
+ break :blk table ;
55
+ };
56
+
57
+ crc : I ,
58
+
59
+ pub fn init () Self {
60
+ const initial = if (algorithm .reflect_input )
61
+ @bitReverse (@as (I , algorithm .initial )) >> (@bitSizeOf (I ) - @bitSizeOf (W ))
62
+ else
63
+ @as (I , algorithm .initial ) << (@bitSizeOf (I ) - @bitSizeOf (W ));
64
+ return Self { .crc = initial };
65
+ }
66
+
67
+ inline fn tableEntry (index : I ) I {
68
+ return lookup_table [@intCast (u8 , index & 0xFF )];
69
+ }
70
+
71
+ pub fn update (self : * Self , bytes : []const u8 ) void {
72
+ var i : usize = 0 ;
73
+ if (@bitSizeOf (I ) <= 8 ) {
74
+ while (i < bytes .len ) : (i += 1 ) {
75
+ self .crc = tableEntry (self .crc ^ bytes [i ]);
76
+ }
77
+ } else if (algorithm .reflect_input ) {
78
+ while (i < bytes .len ) : (i += 1 ) {
79
+ const table_index = self .crc ^ bytes [i ];
80
+ self .crc = tableEntry (table_index ) ^ (self .crc >> 8 );
81
+ }
82
+ } else {
83
+ while (i < bytes .len ) : (i += 1 ) {
84
+ const table_index = (self .crc >> (@bitSizeOf (I ) - 8 )) ^ bytes [i ];
85
+ self .crc = tableEntry (table_index ) ^ (self .crc << 8 );
86
+ }
87
+ }
88
+ }
89
+
90
+ pub fn final (self : Self ) W {
91
+ var c = self .crc ;
92
+ if (algorithm .reflect_input != algorithm .reflect_output ) {
93
+ c = @bitReverse (c );
94
+ }
95
+ if (! algorithm .reflect_output ) {
96
+ c >>= @bitSizeOf (I ) - @bitSizeOf (W );
97
+ }
98
+ return @intCast (W , c ^ algorithm .xor_output );
99
+ }
100
+
101
+ pub fn hash (bytes : []const u8 ) W {
102
+ var c = Self .init ();
103
+ c .update (bytes );
104
+ return c .final ();
105
+ }
106
+ };
107
+ }
108
+
13
109
pub const Polynomial = enum (u32 ) {
14
110
IEEE = 0xedb88320 ,
15
111
Castagnoli = 0x82f63b78 ,
0 commit comments