From 82fb2eecc4ee4752713e05394e96a1daf204bee6 Mon Sep 17 00:00:00 2001 From: sirsegv Date: Tue, 28 May 2024 21:57:08 +0930 Subject: [PATCH 1/5] Update syntax to modern V --- nanoid.v | 54 ++++++++++++++++++++++++------------------------------ 1 file changed, 24 insertions(+), 30 deletions(-) diff --git a/nanoid.v b/nanoid.v index a175c01..ca1842c 100644 --- a/nanoid.v +++ b/nanoid.v @@ -3,17 +3,13 @@ module nanoid import math import crypto.rand -const ( - // default_alphabet is the alphabet used for ID characters by default. - default_alphabet = '_-0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'.runes() - // default length for ID - default_size = 21 -) +// default_alphabet is the alphabet used for ID characters by default. +const default_alphabet = '_-0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'.runes() // get_mask generates bit mask used to obtain bits from the random bytes that are used to get index of random character // from the alphabet. Example: if the alphabet has 6 = (110)_2 characters it is sufficient to use mask 7 = (111)_2 fn get_mask(alphabet_size int) int { - for i := 1; i <= 8; i++ { + for i in 1..9 { mask := (2 << u64(i)) - 1 if mask >= alphabet_size - 1 { return mask @@ -23,7 +19,7 @@ fn get_mask(alphabet_size int) int { } // generate is a low-level function to change alphabet and ID size. -pub fn generate(alphabet string, size int) ?string { +pub fn generate(alphabet string, size int) !string { chars := alphabet.runes() if alphabet.len == 0 || alphabet.len > 255 { @@ -40,10 +36,12 @@ pub fn generate(alphabet string, size int) ?string { step := int(math.ceil(ceil_arg)) mut id := []rune{len: size} - // bytes := []byte{len: step} + bytes := rand.read(step) or { return error(err.msg()) } - for j := 0; true; { - for i := 0; i < step; i++ { + + mut j := 0 + for true { + for i in 0..step { curr_byte := bytes[i] & u8(mask) if curr_byte < u8(chars.len) { id[j] = chars[curr_byte] @@ -55,34 +53,31 @@ pub fn generate(alphabet string, size int) ?string { } } - return error('could not generated') + return error('could not generate') } // must_generate is the same as generate but panics on error. pub fn must_generate(alphabet string, size int) string { - id := generate(alphabet, size) or { panic(err.msg()) } - return id + return generate(alphabet, size) or { panic(err.msg()) } +} + +@[params] +pub struct NanoIDParams { + size int = 21 } // new generates secure URL-friendly unique ID. // Accepts optional parameter - length of the ID to be generated (21 by default). -pub fn new(l ...int) ?string { - mut size := int(0) - if l.len == 0 { - size = default_size - } else if l.len == 1 { - size = l[0] - if size <= 0 { - return error('size must be positive integer') - } - } else { - return error('unexpected parameter') +pub fn new(p NanoIDParams) !string { + mut size := p.size + if size <= 0 { + return error('size must be positive integer') } - bytes := rand.read(size) or { return error(err.msg()) } + bytes := rand.read(size)! mut id := []rune{len: size} - for i := 0; i < size; i++ { + for i in 0..size { id[i] = default_alphabet[bytes[i] & 63] } @@ -90,7 +85,6 @@ pub fn new(l ...int) ?string { } // must is the same as new but panics on error. -pub fn must(l ...int) string { - id := new(...l) or { panic(err.msg()) } - return id +pub fn must(p NanoIDParams) string { + return new(p) or { panic(err.msg()) } } From f76eaf8f2c27e7ce23817e8286db30e35d8cd952 Mon Sep 17 00:00:00 2001 From: sirsegv Date: Mon, 23 Sep 2024 23:18:18 +0930 Subject: [PATCH 2/5] update function names to be more consistent with modern V --- nanoid.v | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/nanoid.v b/nanoid.v index ca1842c..8c53316 100644 --- a/nanoid.v +++ b/nanoid.v @@ -18,8 +18,8 @@ fn get_mask(alphabet_size int) int { return 0 } -// generate is a low-level function to change alphabet and ID size. -pub fn generate(alphabet string, size int) !string { +// generate_opt is a low-level function to change alphabet and ID size. +pub fn generate_opt(alphabet string, size int) !string { chars := alphabet.runes() if alphabet.len == 0 || alphabet.len > 255 { @@ -36,9 +36,9 @@ pub fn generate(alphabet string, size int) !string { step := int(math.ceil(ceil_arg)) mut id := []rune{len: size} - + bytes := rand.read(step) or { return error(err.msg()) } - + mut j := 0 for true { for i in 0..step { @@ -56,19 +56,20 @@ pub fn generate(alphabet string, size int) !string { return error('could not generate') } -// must_generate is the same as generate but panics on error. -pub fn must_generate(alphabet string, size int) string { +// generate is the same as generate_opt but panics on error. +pub fn generate(alphabet string, size int) string { return generate(alphabet, size) or { panic(err.msg()) } } +// Allows the id size to be passed as a parameter @[params] pub struct NanoIDParams { size int = 21 } -// new generates secure URL-friendly unique ID. +// new_opt generates secure URL-friendly unique ID. // Accepts optional parameter - length of the ID to be generated (21 by default). -pub fn new(p NanoIDParams) !string { +pub fn new_opt(p NanoIDParams) !string { mut size := p.size if size <= 0 { return error('size must be positive integer') @@ -84,7 +85,7 @@ pub fn new(p NanoIDParams) !string { return id[..size].string() } -// must is the same as new but panics on error. -pub fn must(p NanoIDParams) string { +// new is the same as new_opt but panics on error. +pub fn new(p NanoIDParams) string { return new(p) or { panic(err.msg()) } } From 478a956edcd36cb5773c7703c0f5b34f2d0caf12 Mon Sep 17 00:00:00 2001 From: sirsegv Date: Mon, 23 Sep 2024 23:18:30 +0930 Subject: [PATCH 3/5] update license --- LICENSE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LICENSE b/LICENSE index 7bc8ead..27ef29a 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2021 invipal +Copyright (c) 2024 sirsegv, invipal Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal From 8cb5b40f6e0bb71c35f0c6c8643b4e506aa4c74a Mon Sep 17 00:00:00 2001 From: sirsegv Date: Mon, 23 Sep 2024 23:24:17 +0930 Subject: [PATCH 4/5] update readme to reflect new changes --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 502cb0b..52ec9a8 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ This package is V implementation of [NanoID](https://github.com/ai/nanoid) -Generated from [Go Nanoid](https://github.com/matoous/go-nanoid) +It was forked from [invipal's implemenation](https://github.com/invipal/nanoid), which itself was generated from [Go Nanoid](https://github.com/matoous/go-nanoid) **Safe.** It uses cryptographically strong random generator. @@ -23,7 +23,7 @@ and has the same number of unique options in just 22 symbols instead of 36. Via vpm ```bash -$ v install invipal.nanoid +$ v install squidink7.nanoid ``` ## Usage @@ -31,13 +31,13 @@ $ v install invipal.nanoid Generate ID ```v -id := nanoid.new() or { 'error' } +id := nanoid.new() ``` Generate ID with a custom alphabet and length ```v -id := nanoid.generate('erzurum', 25) or { 'error' } +id := nanoid.generate('erzurum', 25) ``` ## Contribution From a2a740a188a3aed6324ab41b312051891312dc67 Mon Sep 17 00:00:00 2001 From: sirsegv Date: Mon, 23 Sep 2024 23:28:08 +0930 Subject: [PATCH 5/5] call correct functions --- nanoid.v | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/nanoid.v b/nanoid.v index 8c53316..57dee84 100644 --- a/nanoid.v +++ b/nanoid.v @@ -58,7 +58,7 @@ pub fn generate_opt(alphabet string, size int) !string { // generate is the same as generate_opt but panics on error. pub fn generate(alphabet string, size int) string { - return generate(alphabet, size) or { panic(err.msg()) } + return generate_opt(alphabet, size) or { panic(err.msg()) } } // Allows the id size to be passed as a parameter @@ -87,5 +87,5 @@ pub fn new_opt(p NanoIDParams) !string { // new is the same as new_opt but panics on error. pub fn new(p NanoIDParams) string { - return new(p) or { panic(err.msg()) } + return new_opt(p) or { panic(err.msg()) } }