Skip to content

Instantly share code, notes, and snippets.

@notcancername
Created March 11, 2024 18:25
Show Gist options
  • Save notcancername/ae63455b56c64a294d1cfeac364581eb to your computer and use it in GitHub Desktop.
Save notcancername/ae63455b56c64a294d1cfeac364581eb to your computer and use it in GitHub Desktop.
Convert a /N subnet to an IP range.
const std = @import("std");
pub fn main() !void {
var rd_state = std.io.bufferedReader(std.io.getStdIn().reader());
const rd = rd_state.reader();
var wr_state = std.io.bufferedWriter(std.io.getStdOut().writer());
const wr = wr_state.writer();
var buf: [64]u8 = undefined;
while (true) {
const s = rd.readUntilDelimiter(&buf, '\n') catch |e| switch (e) {
error.EndOfStream => break,
else => return e,
};
var line = std.mem.splitScalar(u8, s, '/');
const ip_text = line.first();
const ip_bytes = parse: {
var periods = std.mem.splitScalar(u8, ip_text, '.');
const a: u32 = std.fmt.parseInt(u8, periods.first(), 10) catch continue;
const b: u32 = std.fmt.parseInt(u8, periods.next() orelse continue, 10) catch continue;
const c: u32 = std.fmt.parseInt(u8, periods.next() orelse continue, 10) catch continue;
const d: u32 = std.fmt.parseInt(u8, periods.next() orelse continue, 10) catch continue;
break :parse a << 24 | b << 16 | c << 8 | d;
};
const subnet = std.fmt.parseInt(u5, line.next() orelse continue, 10) catch continue;
const subnet_mask = (@as(u32, 1) << @intCast(32 - @as(u6, subnet))) - 1;
const ip_start = ip_bytes & ~subnet_mask;
const ip_end = ip_start | subnet_mask;
std.mem.writeInt(u32, buf[0..4], ip_start, .big);
std.mem.writeInt(u32, buf[4..8], ip_end, .big);
try wr.print("{d}.{d}.{d}.{d}-{d}.{d}.{d}.{d}\n", .{buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6], buf[7]});
}
try wr_state.flush();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment