authorgravatar for hello@nektro.netMeghan Denny <hello@nektro.net> 2021-12-12 15:19:50 -08:00
committergravatar for hello@nektro.netMeghan Denny <hello@nektro.net> 2021-12-12 15:19:50 -08:00
log72b89890344a2f9b13d14ec95f282f0e2c1b0dc7
tree8ca39a54f213c2d493baad6f408e44ef2e522ee4
parent253618aa24bfe2a670e5114c6681bda034d77b05

add hashFile


1 files changed, 64 insertions(+), 0 deletions(-)

src/lib.zig+64
...@@ -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
145pub 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
160pub 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
190fn 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}