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/cw3/src/main.zig

218 lines
6.1 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 print(comptime str: []const u8, args: anytype) void {
stdout.print(str, args) catch unreachable;
}
fn println(comptime str: []const u8, args: anytype) void {
print(str ++ "\n", args);
}
//const n: u512 = 7405872386298001828045412304885395957447735855540402226273272018863616985100578690399814241980651881616439657049448993379923363875365701026162288146836853;
const n: u512 = 70666344586694209770041979947;
var sqrt: u512 = undefined;
const Pack = struct {
const Self = @This();
alloc: std.mem.Allocator,
n1: u512,
n2: u512,
fn init(alloc: std.mem.Allocator, n1: u512, n2: u512) !*Self {
const self = try alloc.create(Self);
self.n1 = n1;
self.n2 = n2;
self.alloc = alloc;
return self;
}
fn same(self: *Self, other: *Self) bool {
return (self.n1 == other.n1 and self.n2 == other.n2) or (self.n1 == other.n2 and self.n2 == other.n1);
}
fn sameNumbers(self: *Self, n1: u512, n2: u512) bool {
return (self.n1 == n1 and self.n2 == n2);
}
fn print(self: *Self) void {
println("{} {}", .{ self.n1, self.n2 });
}
fn deinit(self: *Self) void {
self.alloc.destroy(self);
}
};
const PackList = std.ArrayList(*Pack);
fn addPackNumbers(self: *PackList, n1: u512, n2: u512) !void {
for (self.items, 0..) |item, j| {
var i = item;
if (n1 == i.n1) {
if (n2 == i.n2) {
return;
} else if (n2 > i.n2) {
var pack = try Pack.init(self.allocator, n1, n2);
try self.insert(j + 1, pack);
}
}
if (n1 < i.n1) {
var pack = try Pack.init(self.allocator, n1, n2);
try self.insert(j, pack);
return;
}
}
var pack = try Pack.init(self.allocator, n1, n2);
try self.append(pack);
}
fn base3Mask(val: u512, size: usize) u512 {
return val % std.math.pow(u512, 10, size);
}
var nBase: u512 = undefined;
pub fn main() !void {
var alloctor = std.heap.ArenaAllocator.init(std.heap.page_allocator);
defer alloctor.deinit();
var alloc = alloctor.allocator();
sqrt = std.math.sqrt(n);
nBase = base3Mask(n, 1);
println("BaseMask {}", .{nBase});
var items = try searchAcc(alloc, 1);
var toRemove = std.ArrayList(usize).init(alloc);
defer toRemove.deinit();
var cpuCount = try std.Thread.getCpuCount();
var threads = try alloc.alloc(std.Thread, cpuCount);
defer alloc.free(threads);
var results = try alloc.alloc(PackList, cpuCount);
defer alloc.free(results);
for (2..512) |acc| {
nBase = base3Mask(n, acc);
toRemove.clearRetainingCapacity();
println("Stared threaded work on {}", .{acc});
for (0..cpuCount) |id| {
threads[id] = try std.Thread.spawn(.{
.stack_size = 1024 * 1024 * 1024,
.allocator = alloc,
}, threadSearch, .{ items, id, cpuCount, acc, results });
}
for (0..cpuCount) |id| {
threads[id].join();
}
var total: u64 = 0;
for (results) |result| {
total += result.items.len;
}
println("Finish threaded work on {} total {}", .{ acc, total });
for (items.items) |item| {
item.deinit();
}
items.clearRetainingCapacity();
for (results) |result| {
//for (result.items) |toAdd| {
//try addPack(&newToAdd, toAdd);
//}
try items.appendSlice(result.items);
result.deinit();
}
// println("results for {}", .{acc});
// for (items.items) |item| {
// item.print();
// }
if (acc == 10) {
println("For items: {}", .{items.items.len});
for (items.items) |item| {
item.print();
}
break;
} else {
println("For finished {}; items: {}", .{ acc, items.items.len });
}
}
}
fn threadSearch(items: PackList, id: usize, threadCount: usize, acc: u64, results: []PackList) !void {
const max = @max(items.items.len / threadCount, 1);
//var returned = PackList.init(items.allocator);
var returned = PackList.init(std.heap.page_allocator);
const len = items.items.len;
for (0..max) |_i| {
var i = id + _i * threadCount;
if (i >= len) {
break;
}
var item = items.items[i];
if (!verifyAccuracy(item, acc)) {
//println("{} {} does not hold for acc {}", .{ item.n1, item.n2, acc });
try searchPackAcc(&returned, acc, item);
} else {
try addPackNumbers(&returned, @min(item.n1, item.n2), @max(item.n1, item.n2));
}
}
results[id] = returned;
return;
}
fn searchPackAcc(packList: *PackList, acc: u64, pack: *Pack) !void {
var size_n1: u512 = std.math.pow(u512, 10, std.math.log10_int(pack.n1) + 1);
var size_n2: u512 = std.math.pow(u512, 10, std.math.log10_int(pack.n2) + 1);
for (0..10) |_i| {
var i = _i * size_n1 + pack.n1;
for (0..10) |_j| {
var j = _j * size_n2 + pack.n2;
var mul: u512 = i * j;
if (mul == n) {
println("Found them {} {}!", .{ j, i });
std.os.exit(1);
}
if (mul > n) break;
var mulMask = base3Mask(mul, acc);
if (mulMask == nBase) {
try addPackNumbers(packList, @min(i, j), @max(i, j));
}
}
}
}
fn searchAcc(alloc: std.mem.Allocator, acc: u64) !PackList {
var packList = PackList.init(alloc);
for (0..10) |i| {
for (0..10) |j| {
var mul: u512 = i * j;
if (mul > n) break;
var mulMask = base3Mask(mul, acc);
if (mulMask == nBase) {
try addPackNumbers(&packList, @min(i, j), @max(i, j));
}
}
}
return packList;
}
fn verifyAccuracy(pack: *Pack, acc: u64) bool {
var mulMask = base3Mask(pack.n1 * pack.n2, acc);
return mulMask == nBase;
}