Issue with Password Generator

D:\ZigProjects\Password_Generator> zig run ./src/main.zig
src\main.zig:10:44: error: member function expected 2 argument(s), found 1
    length = try std.io.getStdIn().reader().readInt(usize);
                 ~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~
D:\Programs\zig-windows-x86_64\lib\std\io.zig:240:20: note: function declared here
        pub inline fn readInt(self: Self, comptime T: type, endian: std.builtin.Endian) NoEofError!T {
const std = @import("std");

pub fn main() !void {
    const stdout = std.io.getStdOut().writer();
    const allocator = std.heap.page_allocator;

    // Prompt the user for the desired password length
    try stdout.print("Length: ", .{});
    var length: usize = 0;
    length = try std.io.getStdIn().reader().readInt(usize);

    // Validate the password length
    if (length <= 0) {
        try stdout.print("Password length must be >= 1!\n", .{});
        return;
    }

    // Allocate memory for the password
    const password = try allocator.alloc(u8, length + 1);
    defer allocator.free(password);

    // Define character pools
    const digits = "0123456789";
    const lowers = "abcdefghijklmnopqrstuvwxyz";
    const uppers = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    const symbols = "!@#$%^&*()";

    // Seed the random number generator
    var rng = std.rand.DefaultPrng.init(std.time.nanoTimestamp());

    // Generate the password
    var passwordIndex: usize = 0;
    for (password[0..length]) |_| {
        const char_type = rng.random() % 4;
        switch (char_type) {
            0 => password[passwordIndex] = digits[rng.random() % digits.len],
            1 => password[passwordIndex] = lowers[rng.random() % lowers.len],
            2 => password[passwordIndex] = uppers[rng.random() % uppers.len],
            else => password[passwordIndex] = symbols[rng.random() % symbols.len],
        }
        passwordIndex += 1;
    }

    // Null-terminate the password
    password[length] = 0;

    // Print the generated password
    try stdout.print("Password: {s}\n", .{password});
}

readInt expects the byte endian, ie what direction to read the bits
readInt(usize, .little)

docs master or 0.13.0

1 Like

Then, this error occurred:

PS D:\ZigProjects\Password_Generator> zig run ./src/main.zig
src\main.zig:29:19: error: root source file struct 'std' has no member named 'rand'
    var rng = std.rand.DefaultPrng.init(std.time.nanoTimestamp());

Zig version

0.14.0-dev.2634+b36ea592b

https://ziglang.org/documentation/master/std/

Here you can search through the standard library documentation.

If you search for DefaulrPrng, you will see that it lives in std.Random.
There is no std.rand module.

2 Likes

In 0.14.0 std.rand became std.Random, I’ve hit this recently when updating my old projects.

1 Like

How do you fix this issue?

Find and replace std.rand with std.Random

1 Like
const std = @import("std");

pub fn main() !void {
    const stdout = std.io.getStdOut().writer();
    const stdin = std.io.getStdIn().reader();
    const allocator = std.heap.page_allocator;

    // Prompt the user for the desired password length
    try stdout.print("Length: ", .{});
    const length_input = try allocator.alloc(u8, 64);
    defer allocator.free(length_input);

    const length_str = try stdin.readUntilDelimiterOrEof(length_input, '\n') orelse return;
    const length: usize = try std.fmt.parseInt(usize, length_str, 10);

    // Validate the password length
    if (length <= 0) {
        try stdout.print("Password length must be >= 1!\n", .{});
        return;
    }

    // Allocate memory for the password
    const password = try allocator.alloc(u8, length + 1);
    defer allocator.free(password);

    // Define character pools
    const digits = "0123456789";
    const lowers = "abcdefghijklmnopqrstuvwxyz";
    const uppers = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    const symbols = "!@#$%^&*()";

    // Seed the random number generator
    var rng = std.Random.DefaultPrng.init(std.time.nanoTimestamp());

    // Generate the password
    for (password[0..length]) |i| {
        const char_type = rng.int(u8) % 4;
        password[i] = switch (char_type) {
            0 => digits[rng.int(u8) % digits.len],
            1 => lowers[rng.int(u8) % lowers.len],
            2 => uppers[rng.int(u8) % uppers.len],
            else => symbols[rng.int(u8) % symbols.len],
        };
    }

    // Null-terminate the password
    password[length] = 0;

    // Print the generated password
    try stdout.print("Password: {s}\n", .{password});
}

Error

PS D:\ZigProjects\Password_Generator> zig run ./src/main.zig
src\main.zig:33:65: error: expected type 'u64', found 'i128'
    var rng = std.Random.DefaultPrng.init(std.time.nanoTimestamp());

This is telling you that nanoTimestamp() returns i128, but DefaultPrng.init() expects i64.

Zig wants you to convert the type yourself so that you’re aware of any consequences.

https://ziglang.org/documentation/master/#Casting

One simple answer might be to use milliTimestamp() Zig Documentation

Thank you to your feedback, as followed to your guidance, butI still encountered problem

const std = @import("std");

pub fn main() !void {
    const stdout = std.io.getStdOut().writer();
    const stdin = std.io.getStdIn().reader();
    const allocator = std.heap.page_allocator;
    // Prompt the user for the desired password length
    try stdout.print("Length: ", .{});
    const length_input = try allocator.alloc(u8, 64);
    defer allocator.free(length_input);

    const length_str = try stdin.readUntilDelimiterOrEof(length_input, '\n') orelse return;
    const length: usize = try std.fmt.parseInt(usize, length_str, 10);

    // Validate the password length
    if (length <= 0) {
        try stdout.print("Password length must be >= 1!\n", .{});
        return;
    }

    // Allocate memory for the password
    const password = try allocator.alloc(u8, length + 1);
    defer allocator.free(password);

    // Define character pools
    const digits = "0123456789";
    const lowers = "abcdefghijklmnopqrstuvwxyz";
    const uppers = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    const symbols = "!@#$%^&*()";

    // Seed the random number generator
    var rng = std.Random.DefaultPrng.init(@intToU64(std.time.milliTimestamp()));

    // Generate the password
    for (password[0..length]) |i| {
        const char_type = rng.int(u8) % 4;
        password[i] = switch (char_type) {
            0 => digits[rng.int(u8) % digits.len],
            1 => lowers[rng.int(u8) % lowers.len],
            2 => uppers[rng.int(u8) % uppers.len],
            else => symbols[rng.int(u8) % symbols.len],
        };
    }

    // Null-terminate the password
    password[length] = 0;

    // Print the generated password
    try stdout.print("Password: {s}\n", .{password});
}

Error:

PS D:\ZigProjects\Password_Generator> zig run .\src\main.zig
src\main.zig:32:43: error: invalid builtin function: '@intToU64'
    var rng = std.Random.DefaultPrng.init(@intToU64(std.time.milliTimestamp()));

I suggest reading through the documentation to see the list of builtin functions available. There are several for casting. Documentation - The Zig Programming Language

4 Likes

After going thru the document as you you suggested, I have encountered the hit with my modified code:

const std = @import("std");
const random = @import("std").Random;

pub fn main() !void {
    const stdout = std.io.getStdOut().writer();
    const stdin = std.io.getStdIn().reader();
    const allocator = std.heap.page_allocator;

    // Prompt the user for the desired password length
    try stdout.print("Length: ", .{});
    const length_input = try allocator.alloc(u8, 64);
    defer allocator.free(length_input);

    const length_str = try stdin.readUntilDelimiterOrEof(length_input, '\n') orelse return;
    const length: usize = try std.fmt.parseInt(usize, length_str, 10);

    // Validate the password length
    if (length <= 0) {
        try stdout.print("Password length must be >= 1!\n", .{});
        return;
    }

    // Allocate memory for the password
    const password = try allocator.alloc(u8, length + 1);
    defer allocator.free(password);

    // Define character pools
    const digits = "0123456789";
    const lowers = "abcdefghijklmnopqrstuvwxyz";
    const uppers = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    const symbols = "!@#$%^&*()";

    // Seed the random number generator
    var rng = random.DefaultPrng.init(std.time.milliTimestamp());

    // Generate the password
    for (password[0..length]) |i| {
        const char_type = rng.nextInt(u8) % 4;
        password[i] = switch (char_type) {
            0 => digits[rng.nextInt(u8) % digits.len],
            1 => lowers[rng.nextInt(u8) % lowers.len],
            2 => uppers[rng.nextInt(u8) % uppers.len],
            else => symbols[rng.nextInt(u8) % symbols.len],
        };
    }

    // Null-terminate the password
    password[length] = 0;

    // Print the generated password
    try stdout.print("Password: {s}\n", .{password});
}

Error:

PS D:\ZigProjects\Password_Generator> zig run .\src\main.zig
src\main.zig:34:62: error: expected type 'u64', found 'i64'
    var rng = random.DefaultPrng.init(std.time.milliTimestamp());
                                      ~~~~~~~~~~~~~~~~~~~~~~~^~
src\main.zig:34:62: note: unsigned 64-bit int cannot represent all possible signed 64-bit values
D:\Programs\Zig\lib\std\Random\Xoshiro256.zig:11:21: note: parameter type declared here
pub fn init(init_s: u64) Xoshiro256

@sisovin Is there a reason you use md as language for your code blocks instead of the default?
The default Zig seems like a better match to me.

const seed: u64 = @intCast(std.time.milliTimestamp());
var rng = random.DefaultPrng.init(seed);

Modified code:

const std = @import("std");
const random = @import("std").Random;

pub fn main() !void {
    const stdout = std.io.getStdOut().writer();
    const stdin = std.io.getStdIn().reader();
    const allocator = std.heap.page_allocator;

    // Prompt the user for the desired password length
    try stdout.print("Length: ", .{});
    const length_input = try allocator.alloc(u8, 64);
    defer allocator.free(length_input);

    const length_str = try stdin.readUntilDelimiterOrEof(length_input, '\n') orelse return;
    const length: usize = try std.fmt.parseInt(usize, length_str, 10);

    // Validate the password length
    if (length <= 0) {
        try stdout.print("Password length must be >= 1!\n", .{});
        return;
    }

    // Allocate memory for the password
    const password = try allocator.alloc(u8, length + 1);
    defer allocator.free(password);

    // Define character pools
    const digits = "0123456789";
    const lowers = "abcdefghijklmnopqrstuvwxyz";
    const uppers = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    const symbols = "!@#$%^&*()";

    // Seed the random number generator
    const timeStamp = std.time.milliTimestamp();
    std.debug.print("Seed: {}\n", .{timeStamp});
    const bit_seed: u64 = @bitCast(timeStamp);
    var rng = random.DefaultPrng.init(bit_seed);

    // Generate the password
    for (password[0..length]) |i| {
        const char_type = rng.random.u8() % 4;
        password[i] = switch (char_type) {
            0 => digits[rng.random.u8() % digits.len],
            1 => lowers[rng.random.u8() % lowers.len],
            2 => uppers[rng.random.u8() % uppers.len],
            else => symbols[rng.random.u8() % symbols.len],
        };
    }

    // Null-terminate the password
    password[length] = 0;

    // Print the generated password
    try stdout.print("Password: {s}\n", .{password});
}

Error:

PS D:\ZigProjects\Password_Generator> zig run .\src\main.zig
src\main.zig:41:31: error: no field named 'random' in struct 'Random.Xoshiro256'
        const char_type = rng.random.u8() % 4;
                              ^~~~~~
D:\Programs\Zig\lib\std\Random\Xoshiro256.zig:1:1: note: struct declared here
//! Xoshiro256++ - http://xoroshiro.di.unimi.it/

https://ziglang.org/documentation/master/std/#std.Random.Xoshiro256

Again, please refer to the documentation of the API you are trying to use. How are you coming up with your initial guesses? :smiley:

Xoshiro256 returns a u64 value with the next function (see documentation). After calling next you have to truncate the value to your desired range.

P.S: Most of the time, if you click on [src] in the documentation pages and scroll down or search for “test” you will find some usage examples.

1 Like

Code modified:

const std = @import(“std”);
const random = @import(“std”).Random;

pub fn main() !void {
const stdout = std.io.getStdOut().writer();
const stdin = std.io.getStdIn().reader();
const allocator = std.heap.page_allocator;

// Prompt the user for the desired password length
try stdout.print("Length: ", .{});
const length_input = try allocator.alloc(u8, 64);
defer allocator.free(length_input);

var length_str = try stdin.readUntilDelimiterOrEof(length_input, '\n') orelse return;
// Manually remove any newline characters
while (length_str[length_str.len - 1] == '\n' or length_str[length_str.len - 1] == '\r') {
    length_str = length_str[0 .. length_str.len - 1];
}
std.debug.print("Length: {s}\n", .{length_str});

const length: usize = try std.fmt.parseInt(usize, length_str, 10);

// Validate the password length
if (length <= 0) {
    try stdout.print("Password length must be >= 1!\n", .{});
    return;
}

// Allocate memory for the password
const password = try allocator.alloc(u8, length + 1);
defer allocator.free(password);

// Define character pools
const digits = "0123456789";
const lowers = "abcdefghijklmnopqrstuvwxyz";
const uppers = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
const symbols = "!@#$%^&*()";

// Seed the random number generator
const timeStamp = std.time.milliTimestamp();
std.debug.print("Seed: {}\n", .{timeStamp});
const bit_seed: u64 = @bitCast(timeStamp);
var rng = random.DefaultPrng.init(bit_seed);

// Generate the password
for (password[0..length]) |i| {
    const char_type: u8 = @intCast(rng.next() % 4);
    password[i] = switch (char_type) {
        0 => digits[@intCast(rng.next() % digits.len)],
        1 => lowers[@intCast(rng.next() % lowers.len)],
        2 => uppers[@intCast(rng.next() % uppers.len)],
        else => symbols[@intCast(rng.next() % symbols.len)],
    };
}

// Null-terminate the password
password[length] = 0;

// Print the generated password
try stdout.print("Password: {s}\n", .{password});

}

Hit Error

PS D:\ZigProjects\Password_Generator> zig run .\src\main.zig
Length: 32
Length: 32
Seed: 1736844486057
thread 8136 panic: index out of bounds: index 170, len 33
D:\ZigProjects\Password_Generator\src\main.zig:48:17: 0x7ff7110d1d15 in main (main.exe.obj)
password[i] = switch (char_type) {

New Code modified:

const std = @import("std");
const random = @import("std").Random;

pub fn main() !void {
    const stdout = std.io.getStdOut().writer();
    const stdin = std.io.getStdIn().reader();
    const allocator = std.heap.page_allocator;

    // Prompt the user for the desired password length
    try stdout.print("Length: ", .{});
    const length_input = try allocator.alloc(u8, 64);
    defer allocator.free(length_input);

    var length_str = try stdin.readUntilDelimiterOrEof(length_input, '\n') orelse return;
    // Manually remove any newline characters
    while (length_str[length_str.len - 1] == '\n' or length_str[length_str.len - 1] == '\r') {
        length_str = length_str[0 .. length_str.len - 1];
    }
    std.debug.print("Length: {s}\n", .{length_str});

    const length: usize = try std.fmt.parseInt(usize, length_str, 10);

    // Validate the password length
    if (length <= 0) {
        try stdout.print("Password length must be >= 1!\n", .{});
        return;
    }

    // Allocate memory for the password
    const password = try allocator.alloc(u8, length + 1);
    defer allocator.free(password);

    // Define character pools
    const digits = "0123456789";
    const lowers = "abcdefghijklmnopqrstuvwxyz";
    const uppers = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    const symbols = "!@#$%^&*()";

    // Seed the random number generator
    const timeStamp = std.time.milliTimestamp();
    std.debug.print("Seed: {}\n", .{timeStamp});
    const bit_seed: u64 = @intCast(timeStamp);
    var rng = random.DefaultPrng.init(bit_seed);

    // Generate the password
    for (password[0..length]) |i| {
        const char_type: u8 = @truncate(rng.next() % 4);
        const digit_idx: u8 = @truncate(rng.next() % digits.len);
        const lower_idx: u8 = @truncate(rng.next() % lowers.len);
        const upper_idx: u8 = @truncate(rng.next() % uppers.len);
        const symbol_idx: u8 = @truncate(rng.next() % symbols.len);

        std.debug.print("Indices: digit_idx = {}, lower_idx = {}, upper_idx = {}, symbol_idx = {}\n", .{ digit_idx, lower_idx, upper_idx, symbol_idx });

        password[i] = switch (char_type) {
            0 => digits[digit_idx],
            1 => lowers[lower_idx],
            2 => uppers[upper_idx],
            else => symbols[symbol_idx],
        };
    }

    // Null-terminate the password
    password[length] = 0;

    // Print the generated password
    try stdout.print("Password: {s}\n", .{password});
}

Hit the error:

PS D:\ZigProjects\Password_Generator> zig run .\src\main.zig
Length: 32
Length: 32
Seed: 1736851814909
Indices: digit_idx = 2, lower_idx = 25, upper_idx = 4, symbol_idx = 5
thread 300 panic: index out of bounds: index 170, len 33
D:\ZigProjects\Password_Generator\src\main.zig:55:17: 0x7ff63b031e28 in main (main.exe.obj)
        password[i] = switch (char_type) {
                ^
D:\Programs\Zig\lib\std\start.zig:475:53: 0x7ff63b0338f7 in WinStartup (main.exe.obj)
    std.os.windows.ntdll.RtlExitUserProcess(callMain());
                                                    ^
???:?:?: 0x7ffd3a4e259c in ??? (KERNEL32.DLL)
???:?:?: 0x7ffd3c52af37 in ??? (ntdll.dll)

i gets the value 170 because that is the first character in the password (password[0] → i).
You probably want i to be an index and not the password characters.

for (0..length) |i| {
2 Likes

I want to generate the password, but I cannot find the way how to resolve it. Do you any way to resolve this hit of error?
Indices: digit_idx = 2, lower_idx = 25, upper_idx = 4, symbol_idx = 5
thread 300 panic: index out of bounds: index 170, len 33