This repository has been archived on 2024-01-04. You can view files and clone it, but cannot push or open issues or pull requests.
ComputerSecurity/cw1/src/main.zig

176 lines
4.4 KiB
Zig
Raw Normal View History

2023-11-03 12:09:31 +00:00
const std = @import("std");
const stdout = std.io.getStdOut().writer();
fn println(comptime str: []const u8, args: anytype) void {
print(str ++ "\n", args);
}
fn print(comptime str: []const u8, args: anytype) void {
stdout.print(str, args) catch {};
}
fn parse(comptime str: []const u8) [10]u8 {
var new = std.mem.zeroes([10]u8);
for (0..10) |i| {
new[i] = str[i] - 65;
}
return new;
}
var p1 = parse("VRDTOUAPZX");
var p2 = parse("JSXCKEAGDE");
var count: u64 = 0;
const ArrayListU8 = std.ArrayList(u8);
const Node = struct {
value: u8,
depth: u8,
tree: *Tree,
};
const Tree = struct {
alloc: std.mem.Allocator,
nodes: std.AutoHashMap(u8, *Node),
const Self = @This();
fn init(alloc: std.mem.Allocator) !*Self {
var new = try alloc.create(Tree);
new.alloc = alloc;
new.nodes = std.AutoHashMap(u8, *Node).init(alloc);
return new;
}
fn add_word(self: *Self, word: []const u8) !void {
var tree_ptr: *Self = self;
var depth: u8 = 0;
for (word) |cu| {
const c = cu - 65;
if (tree_ptr.*.nodes.get(c)) |node| {
tree_ptr = node.tree;
} else {
var new_node = try self.alloc.create(Node);
new_node.value = c;
new_node.depth = depth;
new_node.tree = try Self.init(self.alloc);
try tree_ptr.*.nodes.put(c, new_node);
tree_ptr = new_node.tree;
}
depth += 1;
}
}
};
pub fn main() !void {
var allocator = std.heap.GeneralPurposeAllocator(.{}){};
var alloc = allocator.allocator();
const args = try std.process.argsAlloc(alloc);
if (args.len == 3) {
if (args[1].len != 10 and args[2].len != 10) {
println("Invalid args", .{});
return;
}
println("Using c1={s} c2={s}", .{ args[1], args[2] });
for (0..10) |i| {
p1[i] = args[1][i] - 65;
p2[i] = args[2][i] - 65;
}
}
var words = @embedFile("./10letterwordslist.txt");
var root = try Tree.init(alloc);
var split = std.mem.split(u8, words, "\r\n");
while (split.next()) |item| {
if (item.len == 10) {
try root.add_word(item);
}
}
var sr = try search3(0, root, root);
if (sr.items.len == 0) {
println("No results found \n", .{});
return;
}
println("items: {}", .{sr.items.len});
var r = sr.items[0];
var r1 = [10]u8{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
var r2 = [10]u8{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
for (p1, p2, r, 0..) |p_1, p_2, k, i| {
r1[i] = ((p_1 + (26 - k)) % 26) + 65;
r2[i] = ((p_2 + (26 - k)) % 26) + 65;
r[i] = k + 65;
}
println("k: {s}", .{r});
println("r1: {s}", .{r1});
println("r2: {s}", .{r2});
println("Checked: {}", .{count});
}
fn search3(depth: u8, tree1: *Tree, tree2: *Tree) !std.ArrayList([]u8) {
var list = std.ArrayList([]u8).init(tree1.alloc);
for (0..26) |validChari| {
var validChar: u8 = @intCast(validChari);
count += 1;
var inv = 26 - validChar;
var v1 = (p1[depth] + inv) % 26;
var v2 = (p2[depth] + inv) % 26;
var new_tree1 = tree1.nodes.get(v1);
var new_tree2 = tree2.nodes.get(v2);
if (new_tree1 == null or new_tree2 == null) {
continue;
}
var sr = try search2(depth + 1, new_tree1.?.tree, new_tree2.?.tree);
if (sr == null) {
continue;
}
var r = sr.?;
r[depth] = validChar;
try list.append(r);
}
return list;
}
fn search2(depth: u8, tree1: *Tree, tree2: *Tree) !?[]u8 {
if (depth == 10) {
return try tree1.alloc.alloc(u8, 10);
}
for (0..26) |validChari| {
var validChar: u8 = @intCast(validChari);
count += 1;
var inv = 26 - validChar;
var v1 = (p1[depth] + inv) % 26;
var v2 = (p2[depth] + inv) % 26;
var new_tree1 = tree1.nodes.get(v1);
var new_tree2 = tree2.nodes.get(v2);
if (new_tree1 == null or new_tree2 == null) {
continue;
}
var sr = try search2(depth + 1, new_tree1.?.tree, new_tree2.?.tree);
if (sr == null) {
continue;
}
var r = sr.?;
r[depth] = validChar;
return r;
}
return null;
}