| ... | @@ -141,3 +141,67 @@ pub fn fileSize(dir: std.fs.Dir, sub_path: string) !usize { | ... | @@ -141,3 +141,67 @@ pub fn fileSize(dir: std.fs.Dir, sub_path: string) !usize { |
| 141 | const s = try f.stat(); | 141 | const s = try f.stat(); |
| 142 | return s.size; | 142 | return s.size; |
| 143 | } | 143 | } |
| | 144 | |
| | 145 | pub const HashFn = enum { |
| | 146 | blake3, |
| | 147 | gimli, |
| | 148 | md5, |
| | 149 | sha1, |
| | 150 | sha224, |
| | 151 | sha256, |
| | 152 | sha384, |
| | 153 | sha512, |
| | 154 | sha3_224, |
| | 155 | sha3_256, |
| | 156 | sha3_384, |
| | 157 | sha3_512, |
| | 158 | }; |
| | 159 | |
| | 160 | pub fn hashFile(alloc: *std.mem.Allocator, dir: std.fs.Dir, sub_path: string, comptime algo: HashFn) !string { |
| | 161 | const file = try dir.openFile(sub_path, .{}); |
| | 162 | defer file.close(); |
| | 163 | const hash = std.crypto.hash; |
| | 164 | const Algo = switch (algo) { |
| | 165 | .blake3 => hash.Blake3, |
| | 166 | .gimli => hash.Gimli, |
| | 167 | .md5 => hash.Md5, |
| | 168 | .sha1 => hash.Sha1, |
| | 169 | .sha224 => hash.sha2.Sha224, |
| | 170 | .sha256 => hash.sha2.Sha256, |
| | 171 | .sha384 => hash.sha2.Sha384, |
| | 172 | .sha512 => hash.sha2.Sha512, |
| | 173 | .sha3_224 => hash.sha3.Sha3_224, |
| | 174 | .sha3_256 => hash.sha3.Sha3_256, |
| | 175 | .sha3_384 => hash.sha3.Sha3_384, |
| | 176 | .sha3_512 => hash.sha3.Sha3_512, |
| | 177 | }; |
| | 178 | const h = &Algo.init(.{}); |
| | 179 | var out: [Algo.digest_length]u8 = undefined; |
| | 180 | var hw = HashWriter(Algo){ .h = h }; |
| | 181 | try pipe(file.reader(), hw.writer()); |
| | 182 | h.final(&out); |
| | 183 | |
| | 184 | var res: [Algo.digest_length * 2]u8 = undefined; |
| | 185 | var fbs = std.io.fixedBufferStream(&res); |
| | 186 | try std.fmt.format(fbs.writer(), "{x}", .{std.fmt.fmtSliceHexLower(&out)}); |
| | 187 | return try alloc.dupe(u8, &res); |
| | 188 | } |
| | 189 | |
| | 190 | fn HashWriter(comptime T: type) type { |
| | 191 | return struct { |
| | 192 | h: *T, |
| | 193 | |
| | 194 | const Self = @This(); |
| | 195 | pub const Error = error{}; |
| | 196 | pub const Writer = std.io.Writer(*Self, Error, write); |
| | 197 | |
| | 198 | fn write(self: *Self, bytes: []const u8) Error!usize { |
| | 199 | self.h.update(bytes); |
| | 200 | return bytes.len; |
| | 201 | } |
| | 202 | |
| | 203 | pub fn writer(self: *Self) Writer { |
| | 204 | return .{ .context = self }; |
| | 205 | } |
| | 206 | }; |
| | 207 | } |