diff --git a/01-git/check-mssilenin/README.md b/01-git/check-mssilenin/README.md
new file mode 100644
index 00000000..71dc00cf
--- /dev/null
+++ b/01-git/check-mssilenin/README.md
@@ -0,0 +1,21 @@
+# Сборка
+```
+zig build-exe check.zig
+```
+
+# Запуск
+```
+./check
+```
+
+# Пример вывода корректного дерева (dir ./correct)
+```
+checking commit hash; commit_hash=eac6b33b5eeae8d1e88a3343fc00e8e9c3a5ab120198aecd5c39665852dd0016
+checking commit hash; commit_hash=ebdd7b80aa4838dc4585af7f7d47b643024be479822f6c59b7c6313ce8322173
+checking commit hash; commit_hash=ea57e88f130debd48188990f1175c6cd891ef11017c1145fbf07f39ec2503aa8
+checking commit hash; commit_hash=86012759befd37636df5cc94ad673676a336616acd8b6156ae1bfdaf77465924
+All is correct!
+```
+
+# Некорректное дерево
+Может вернуться либо ошибка IncorrectHash, в случае неверного хеша в названии файла или директории, либо FileNotFound в случае несуществующего файла или директории
diff --git a/01-git/check-mssilenin/check.zig b/01-git/check-mssilenin/check.zig
new file mode 100644
index 00000000..14ee34e2
--- /dev/null
+++ b/01-git/check-mssilenin/check.zig
@@ -0,0 +1,159 @@
+const std = @import("std");
+const sha2 = std.crypto.hash.sha2;
+const Allocator = std.mem.Allocator;
+
+const GB = 1 << 30;
+const HASH_SIZE = 32;
+const HEX_SIZE = 64;
+
+const ErrorIncorrectTree = error{
+ IncorrectHash,
+ FileNotFound,
+};
+
+fn checkBufHash(buf: []const u8, expected: []const u8) !void {
+ var hash: [HASH_SIZE]u8 = undefined;
+ sha2.Sha256.hash(buf, &hash, .{});
+
+ var slice_hash = std.mem.bytesAsSlice(u8, &hash);
+
+ var hex_bytes: [HEX_SIZE]u8 = undefined;
+ _ = try std.fmt.bufPrint(&hex_bytes, "{}", .{std.fmt.fmtSliceHexLower(slice_hash)});
+ var hex_slice = std.mem.bytesAsSlice(u8, &hex_bytes);
+
+ for (hex_slice, expected) |value1, value2| {
+ if (value1 != value2) {
+ return ErrorIncorrectTree.IncorrectHash;
+ }
+ }
+}
+
+fn readCommit(allocator: Allocator, name: []const u8) ![]const u8 {
+ var file = try std.fs.cwd().openFile(name, .{});
+ const file_buffer = try file.readToEndAlloc(allocator, GB);
+ file.close();
+
+ return file_buffer;
+}
+
+fn readAndCheckCommit(allocator: Allocator, hash: []const u8) ![]const u8 {
+ // read current commit
+ std.debug.print("checking commit hash; commit_hash={s}\n", .{hash});
+ var file_buffer = try readCommit(allocator, hash);
+
+ // check if hash of commit != name
+ try checkBufHash(file_buffer, hash);
+
+ return file_buffer;
+}
+
+fn findDir(allocator: Allocator, root_dir: []const u8, commit_hash: []const u8) ![]const u8 {
+ var current_commit_hash = try allocator.alloc(u8, commit_hash.len);
+ std.mem.copy(u8, current_commit_hash, commit_hash);
+
+ if (std.mem.eql(u8, root_dir, ".")) {
+ return current_commit_hash;
+ }
+
+ var dirs_it = std.mem.split(u8, root_dir, "/");
+
+ while (dirs_it.next()) |dir| {
+ var file_buffer = try readCommit(allocator, current_commit_hash);
+ defer allocator.free(file_buffer);
+
+ // split commit by '\n'
+ var lines = std.mem.split(u8, file_buffer, "\n");
+ while (lines.next()) |line| {
+ // skip empty line
+ if (line.len == 0) {
+ continue;
+ }
+
+ // split line by '/\t'
+ var it = std.mem.split(u8, line, "/\t");
+ var commit_dir = it.next();
+
+ // file -> skip
+ if (it.peek() == null) {
+ continue;
+ }
+
+ // find commit_dir == dir
+ if (std.mem.eql(u8, dir, commit_dir.?)) {
+ allocator.free(current_commit_hash);
+
+ var hash = it.peek().?;
+ current_commit_hash = try allocator.alloc(u8, hash.len);
+ std.mem.copy(u8, current_commit_hash, hash);
+ break;
+ }
+ }
+ }
+
+ if (std.mem.eql(u8, current_commit_hash, commit_hash)) {
+ std.debug.print("dir={s} is not found\n", .{root_dir});
+
+ return ErrorIncorrectTree.FileNotFound;
+ }
+
+ std.debug.print("found dir={s}\n", .{current_commit_hash});
+
+ return current_commit_hash;
+}
+
+fn checkFile(allocator: Allocator, name: []const u8) !void {
+ var file_buffer = try readAndCheckCommit(allocator, name);
+ defer allocator.free(file_buffer);
+}
+
+fn checkDir(allocator: Allocator, name: []const u8) !void {
+ var file_buffer = try readAndCheckCommit(allocator, name);
+ defer allocator.free(file_buffer);
+
+ // split commit by '\n'
+ var lines = std.mem.split(u8, file_buffer, "\n");
+ while (lines.next()) |line| {
+ // skip empty line
+ if (line.len == 0) {
+ continue;
+ }
+
+ // split line by '/\t'
+ var it = std.mem.split(u8, line, "/\t");
+ _ = it.next(); // skip name of dir
+
+ // file (len(it) == 1)
+ if (it.peek() == null) {
+ var file_it = std.mem.split(u8, line, ":\t");
+ _ = file_it.next(); // skip name of file
+
+ try checkFile(allocator, file_it.next().?);
+
+ continue;
+ }
+
+ // dir
+ try checkDir(allocator, it.next().?);
+ }
+}
+
+pub fn main() !void {
+ const allocator = std.heap.page_allocator;
+
+ var args = try std.process.argsAlloc(allocator);
+ defer std.process.argsFree(allocator, args);
+ if (args.len != 3) {
+ std.debug.print("Usage: ./check \n", .{});
+ return;
+ }
+
+ const dir = args[1];
+ const start_hash = args[2];
+
+ var hash = try findDir(allocator, dir, start_hash);
+ defer allocator.free(hash);
+
+ try checkDir(allocator, hash);
+
+ std.debug.print("All is correct!\n", .{});
+}
diff --git a/01-git/check-mssilenin/correct/61ec58ece347e6ac22f5227c642410bfad51e33bd2ca57e1f9d5b85502fa4ddf b/01-git/check-mssilenin/correct/61ec58ece347e6ac22f5227c642410bfad51e33bd2ca57e1f9d5b85502fa4ddf
new file mode 100644
index 00000000..63db2144
--- /dev/null
+++ b/01-git/check-mssilenin/correct/61ec58ece347e6ac22f5227c642410bfad51e33bd2ca57e1f9d5b85502fa4ddf
@@ -0,0 +1,2 @@
+file.txt: ebdd7b80aa4838dc4585af7f7d47b643024be479822f6c59b7c6313ce8322173
+subdir/ ea57e88f130debd48188990f1175c6cd891ef11017c1145fbf07f39ec2503aa8
\ No newline at end of file
diff --git a/01-git/check-mssilenin/correct/86012759befd37636df5cc94ad673676a336616acd8b6156ae1bfdaf77465924 b/01-git/check-mssilenin/correct/86012759befd37636df5cc94ad673676a336616acd8b6156ae1bfdaf77465924
new file mode 100644
index 00000000..2c315a99
--- /dev/null
+++ b/01-git/check-mssilenin/correct/86012759befd37636df5cc94ad673676a336616acd8b6156ae1bfdaf77465924
@@ -0,0 +1 @@
+smth
\ No newline at end of file
diff --git a/01-git/check-mssilenin/correct/ea57e88f130debd48188990f1175c6cd891ef11017c1145fbf07f39ec2503aa8 b/01-git/check-mssilenin/correct/ea57e88f130debd48188990f1175c6cd891ef11017c1145fbf07f39ec2503aa8
new file mode 100644
index 00000000..f465bd25
--- /dev/null
+++ b/01-git/check-mssilenin/correct/ea57e88f130debd48188990f1175c6cd891ef11017c1145fbf07f39ec2503aa8
@@ -0,0 +1 @@
+subdir_file.txt: 86012759befd37636df5cc94ad673676a336616acd8b6156ae1bfdaf77465924
\ No newline at end of file
diff --git a/01-git/check-mssilenin/correct/eac6b33b5eeae8d1e88a3343fc00e8e9c3a5ab120198aecd5c39665852dd0016 b/01-git/check-mssilenin/correct/eac6b33b5eeae8d1e88a3343fc00e8e9c3a5ab120198aecd5c39665852dd0016
new file mode 100644
index 00000000..9bcaaa1e
--- /dev/null
+++ b/01-git/check-mssilenin/correct/eac6b33b5eeae8d1e88a3343fc00e8e9c3a5ab120198aecd5c39665852dd0016
@@ -0,0 +1,2 @@
+file.txt: ebdd7b80aa4838dc4585af7f7d47b643024be479822f6c59b7c6313ce8322173
+subdir/ ea57e88f130debd48188990f1175c6cd891ef11017c1145fbf07f39ec2503aa8
diff --git a/01-git/check-mssilenin/correct/ebdd7b80aa4838dc4585af7f7d47b643024be479822f6c59b7c6313ce8322173 b/01-git/check-mssilenin/correct/ebdd7b80aa4838dc4585af7f7d47b643024be479822f6c59b7c6313ce8322173
new file mode 100644
index 00000000..f8147e4d
--- /dev/null
+++ b/01-git/check-mssilenin/correct/ebdd7b80aa4838dc4585af7f7d47b643024be479822f6c59b7c6313ce8322173
@@ -0,0 +1 @@
+so so
\ No newline at end of file
diff --git a/01-git/check-mssilenin/incorrect_dir_hash/61ec58ece347e6ac22f5227c642410bfad51e33bd2ca57e1f9d5b85502fa4ddf b/01-git/check-mssilenin/incorrect_dir_hash/61ec58ece347e6ac22f5227c642410bfad51e33bd2ca57e1f9d5b85502fa4ddf
new file mode 100644
index 00000000..ad8f9e06
--- /dev/null
+++ b/01-git/check-mssilenin/incorrect_dir_hash/61ec58ece347e6ac22f5227c642410bfad51e33bd2ca57e1f9d5b85502fa4ddf
@@ -0,0 +1 @@
+file.txt: ebdd7b80aa4838dc4585af7f7d47b643024be479822f6c59b7c6313ce8322173
\ No newline at end of file
diff --git a/01-git/check-mssilenin/incorrect_dir_hash/ebdd7b80aa4838dc4585af7f7d47b643024be479822f6c59b7c6313ce8322173 b/01-git/check-mssilenin/incorrect_dir_hash/ebdd7b80aa4838dc4585af7f7d47b643024be479822f6c59b7c6313ce8322173
new file mode 100644
index 00000000..f8147e4d
--- /dev/null
+++ b/01-git/check-mssilenin/incorrect_dir_hash/ebdd7b80aa4838dc4585af7f7d47b643024be479822f6c59b7c6313ce8322173
@@ -0,0 +1 @@
+so so
\ No newline at end of file
diff --git a/01-git/check-mssilenin/incorrect_file_hash/dbdd7b80aa4838dc4585af7f7d47b643024be479822f6c59b7c6313ce8322173 b/01-git/check-mssilenin/incorrect_file_hash/dbdd7b80aa4838dc4585af7f7d47b643024be479822f6c59b7c6313ce8322173
new file mode 100644
index 00000000..f8147e4d
--- /dev/null
+++ b/01-git/check-mssilenin/incorrect_file_hash/dbdd7b80aa4838dc4585af7f7d47b643024be479822f6c59b7c6313ce8322173
@@ -0,0 +1 @@
+so so
\ No newline at end of file
diff --git a/01-git/check-mssilenin/incorrect_file_hash/e67e94fb8713fe93b620dd2f2054fcc11d70d820fedd6a3125247fb93dee8f3f b/01-git/check-mssilenin/incorrect_file_hash/e67e94fb8713fe93b620dd2f2054fcc11d70d820fedd6a3125247fb93dee8f3f
new file mode 100644
index 00000000..242b32a2
--- /dev/null
+++ b/01-git/check-mssilenin/incorrect_file_hash/e67e94fb8713fe93b620dd2f2054fcc11d70d820fedd6a3125247fb93dee8f3f
@@ -0,0 +1 @@
+file.txt: dbdd7b80aa4838dc4585af7f7d47b643024be479822f6c59b7c6313ce8322173
\ No newline at end of file
diff --git a/01-git/check-mssilenin/unknown_file/61ec58ece347e6ac22f5227c642410bfad51e33bd2ca57e1f9d5b85502fa4ddf b/01-git/check-mssilenin/unknown_file/61ec58ece347e6ac22f5227c642410bfad51e33bd2ca57e1f9d5b85502fa4ddf
new file mode 100644
index 00000000..63db2144
--- /dev/null
+++ b/01-git/check-mssilenin/unknown_file/61ec58ece347e6ac22f5227c642410bfad51e33bd2ca57e1f9d5b85502fa4ddf
@@ -0,0 +1,2 @@
+file.txt: ebdd7b80aa4838dc4585af7f7d47b643024be479822f6c59b7c6313ce8322173
+subdir/ ea57e88f130debd48188990f1175c6cd891ef11017c1145fbf07f39ec2503aa8
\ No newline at end of file