Skip to content

Commit

Permalink
Clean up code and add README.
Browse files Browse the repository at this point in the history
  • Loading branch information
monomycelium committed Jun 30, 2024
1 parent fdbbde2 commit b0a22da
Show file tree
Hide file tree
Showing 7 changed files with 50 additions and 145 deletions.
28 changes: 28 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# `rf`: A CLI tool to encrypt and decrypt data using [Rail Fence Cipher](https://en.wikipedia.org/wiki/Rail_fence_cipher).

### build

To build the `rf` executable, you will need [`Zig (version 0.13.0)`](https://ziglang.org/learn/getting-started/#installing-zig). To compile for release:
``` console
$ zig build -Doptimize=ReleaseFast
```

The executable will be compiled as `./zig-out/bin/rf`.

### examples

Encrypt a file in-place using 3 rails:
``` console
$ rf -r3 /path/to/secret_file_to_encrypt
```

To decrypt the file, run the same command, appending "-d" to the arguments.

Encrypt to a file from console input using 3 rails:
``` console
$ rf -r3 > /path/to/new_file
three
```

After inputting data, press `Ctrl+d` twice instead of hitting enter.

15 changes: 1 addition & 14 deletions build.zig
Original file line number Diff line number Diff line change
Expand Up @@ -68,26 +68,13 @@ pub fn build(b: *std.Build) void {
.optimize = optimize,
.link_libc = true,
});

lib_unit_tests.linkLibC();
lib_unit_tests.addIncludePath(b.path("src"));
lib_unit_tests.addCSourceFile(.{.file = b.path("src/rail_fence_cipher.c")});
lib_unit_tests.root_module.addImport("rail_fence_cipher", lib);

lib_unit_tests.root_module.addImport("rail_fence_cipher", lib);
const run_lib_unit_tests = b.addRunArtifact(lib_unit_tests);

const exe_unit_tests = b.addTest(.{
.root_source_file = b.path("src/main.zig"),
.target = target,
.optimize = optimize,
});

const run_exe_unit_tests = b.addRunArtifact(exe_unit_tests);

// Similar to creating the run step earlier, this exposes a `test` step to
// the `zig build --help` menu, providing a way for the user to request
// running the unit tests.
const test_step = b.step("test", "Run unit tests");
test_step.dependOn(&run_lib_unit_tests.step);
test_step.dependOn(&run_exe_unit_tests.step);
}
9 changes: 4 additions & 5 deletions src/main.zig
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,10 @@ pub fn main() !void {
const stdin: bool = std.mem.eql(u8, arg, "-");
const stdout: bool = res.args.stdout != 0 or stdin;

const input: fs.File = if (stdin) std.io.getStdIn()
else fs.cwd().openFile(arg, .{.mode = if (stdout) .read_only else .read_write}) catch |err| {
log.err("failed to open input: {any}\n", .{err});
continue;
};
const input: fs.File = if (stdin) std.io.getStdIn() else fs.cwd().openFile(arg, .{ .mode = if (stdout) .read_only else .read_write }) catch |err| {
log.err("failed to open input: {any}\n", .{err});
continue;
};
defer if (!stdin) input.close();
const output: fs.File = if (stdout) std.io.getStdOut() else input;

Expand Down
49 changes: 0 additions & 49 deletions src/rail_fence_cipher.c

This file was deleted.

11 changes: 0 additions & 11 deletions src/rail_fence_cipher.h

This file was deleted.

44 changes: 17 additions & 27 deletions src/rail_fence_cipher.zig
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,19 @@ const mem = std.mem;
pub fn encode(data: []const u8, key: usize, writer: anytype) !void {
if (key == 0) return error.InvalidKey;
if (key == 1 or data.len <= key) return writer.writeAll(data);

const increment: usize = 2 * (key - 1);

for (0..key) |i| {
var data_index: usize = i;
const edge: u1 = @intFromBool(i == 0 or i == key - 1) ^ 1;
var previous_increment: usize = 2 * i;

while (data_index < data.len) {
try writer.writeByte(data[data_index]);

if (i == 0 or i == key - 1) {
while (data_index < data.len) : (data_index += increment)
try writer.writeByte(data[data_index]);
} else {
var previous_increment: usize = 2 * i;
while (data_index < data.len) {
try writer.writeByte(data[data_index]);
previous_increment = increment - previous_increment;
data_index += previous_increment;
}
previous_increment = increment - previous_increment * edge;
data_index += previous_increment;
}
}
}
Expand All @@ -40,29 +37,22 @@ pub fn decode(reader: anytype, key: usize, buffer: []u8, length: usize) ![]u8 {
}

const increment: usize = 2 * (key - 1);
var count: usize = 0;

outer: for (0..key) |i| {
for (0..key) |i| {
var data_index: usize = i;
const edge: u1 = @intFromBool(i == 0 or i == key - 1) ^ 1;
var previous_increment: usize = 2 * i;

while (data_index < length) {
buffer[data_index] = try reader.readByte();

if (i == 0 or i == key - 1) {
while (data_index < length) : (data_index += increment) {
buffer[data_index] = reader.readByte() catch |e| if (e == error.NoEofError) break :outer else return e;
count += 1;
}
} else {
var previous_increment: usize = 2 * i;
while (data_index < length) {
buffer[data_index] = reader.readByte() catch |e| if (e == error.NoEofError) break :outer else return e;
count += 1;
previous_increment = increment - previous_increment;
data_index += previous_increment;
}
previous_increment = increment - previous_increment * edge;
data_index += previous_increment;
}
}

var buf: []u8 = undefined;
buf.ptr = buffer.ptr;
buf.len = count;
buf.len = length;
return buf;
}
39 changes: 0 additions & 39 deletions test/test.zig
Original file line number Diff line number Diff line change
@@ -1,49 +1,10 @@
const std = @import("std");
const rfc = @import("rail_fence_cipher");
const c = @cImport({
@cInclude("rail_fence_cipher.h");
});

const io = std.io;
const List = std.ArrayList;
const testing = std.testing;

fn testRailFenceEncodeC(
decoded: []const u8,
encoded: []const u8,
rails: usize,
) !void {
const alloc = std.heap.raw_c_allocator;

const res: ?[*]u8 = c.encode(.{.len = decoded.len, .ptr = @constCast(decoded.ptr)}, rails);
if (res == null) return error.Null;

var result: []u8 = undefined;
result.ptr = res.?;
result.len = decoded.len;

try testing.expectEqualStrings(encoded, result);
alloc.free(result);
}

fn testRailFenceDecodeC(
decoded: []const u8,
encoded: []const u8,
rails: usize,
) !void {
const alloc = std.heap.raw_c_allocator;

const res: ?[*]u8 = c.decode(.{.len = encoded.len, .ptr = @constCast(encoded.ptr)}, rails);
if (res == null) return error.Null;

var result: []u8 = undefined;
result.ptr = res.?;
result.len = encoded.len;

try testing.expectEqualStrings(decoded, result);
alloc.free(result);
}

fn testRailFenceEncode(
decoded: []const u8,
encoded: []const u8,
Expand Down

0 comments on commit b0a22da

Please sign in to comment.