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

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.

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

How do you fix this issue?

Find and replace std.rand with std.Random

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

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.

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| {

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