Research
Security News
Quasar RAT Disguised as an npm Package for Detecting Vulnerabilities in Ethereum Smart Contracts
Socket researchers uncover a malicious npm package posing as a tool for detecting vulnerabilities in Etherium smart contracts.
pip install namednumber
Named number is a simple package which generates unique names which correspond one-to-one with numbers.
NamedNumber
subclasses int
, making it versatile and easy to use. This can be used to generate fun names that are easy to rember for
log records, database entries, products, temporary passwords, etc.
Create an integer with a seemingly randomly shuffled name associated with it
from namednumber import NamedNumber
x = NamedNumber(50)
print(f"{x=}") # x=<destructive rhino (50)>
print(str(x)) # destructive rhino
Mapping is one to one and reversible so you can also look up a number by its name
print(int(NamedNumber("destructive rhino"))) # 50
flexible pig
is easier to remember than 116994
Do math on it and get results in the same named format (see fancy_number.py for how this works)
print(f"{x+1=}") # x+1=<crucial impala (51)>
x *= 2
print(f"{x=}") # x=<huge crocodile (100)>
Specify your own format using common wordsets and character sets
y = NamedNumber(422, "Bob saw %4% %adjective% %plural_animals% which were all %color%")
print(f"{y=}") # <Bob saw 3 impressive wombats which were all maroon (422)>
Specify your own custom wordlists
z = NamedNumber(30, "%emotion%_%animal%", emotion=['happy', 'sad', 'angry', 'hungry'])
print(f"{z=}") # z=<happy_rabbit (30)>
Save name formats and use them to generate numbers
from namednumber import RandomizedNameFmt
fmt = RandomizedNameFmt("%emotion% %animal% %hex#5%", emotion=['happy', 'sad', 'angry', 'hungry'])
print(f"{fmt(0)=}") # fmt(0)=<sad skunk 3113e (0)>
print(f"{fmt[1]=}") # fmt[1]=<happy woodchuck a48ef (1)>
print(f"{fmt[2:10:3]=}") # fmt[2:10:3]=[<hungry kookaburra 3ec9f (2)>, <hungry iguana 841c4 (5)>, <sad shark 11041 (8)>]
See the individual values of the components
print(dict(x)) # {'huge': 151, 'crocodile': 29}
namednumber
namednumber 51
namednumber 51 52
namednumber :5
namednumber 10:15
namednumber 20:40:7
namednumber :4 --fmt="%emotion% %pet%" --emotion=["happy","sad","angry","hungry"] --pet=["puppy","kitten","turtle","lizard"]
namednumber :8 --fmt="%emotion% %pet%" --inc --emotion=["happy","sad","angry","hungry"] --pet=["puppy","kitten","turtle","lizard"]
namednumber 50 --seed=321
The default functionality of the NameFmt
object is to use the first wordlist as the high bit, second as next highest,
etc. and to convert a number to a list of indices for the bases. Therefore, it will by default produce ordered incrementing results.
from namednumber import NameFmt
fmt = NameFmt(fmt="%first% %second%", first=["red", "green", "blue"], second=["car", "bike"])
print(fmt[:]) # [<red car (0)>, <red bike (1)>, <green car (2)>, <green bike (3)>, <blue car (4)>, <blue bike (5)>]
In some cases this is the desired result, but in other cases it is not. Therefore, we need some reversible way of scrambling the numbers, so that we instead get this.
fmt = RandomizedNameFmt(fmt="%first% %second%", first=["red", "green", "blue"], second=["car", "bike"])
print(fmt[:]) # [<blue car (0)>, <green bike (1)>, <red car (2)>, <green car (3)>, <red bike (4)>, <blue bike (5)>]
One easy way to do this is to create a one-to-one mapping is to create a shuffled list of numbers and use the
index <-> value
mapping. This works well for small wordsets but scales poorly as it requires you to precompute
the large shuffled list and then store it in memory or some form of a memory-mapped file.
RandomizedNameFmt
works using np.random.permutation
, but it can be very slow to initialize if used with sets of length > (1<<23).
Therefore, due to memory and performance concerns, max_size_allowed = 1 << 23
. Use RandomizedNameFmt.plot_performance
to plot
initialization time for varying sized optionsets.
We don't yet have a great solution, but we have left a few functions which can be overwritten to use whatever shuffling algorithm you desire.
class MyNameFmt(NameFmt):
def init_cipher(self):
# setup here
pass
def encrypt(self, i):
return (7 * i + 23) % self.max_number
def decrypt(self, i):
return int((i - 23 % self.max_number)/7)
my_fmt = MyNameFmt()
my_fmt.plot_encryption(50)
print(my_fmt[:5]) # [<all chimpanzee (0)>, <all doe (1)>, <all fish (2)>, <all goat (3)>, <all horse (4)>]
To allow for additional fine-tuning of the string, we have also included placeholders for stylizing and de-stylizing the names.
class sPoNGEboBNameFmt(RandomizedNameFmt):
def reformat(self, name):
NAME = name.upper()
n = int(len(name)/2 + 1)
upper = self.rng.permutation([0]*n + [1]*n)
return "".join([NAME[i] if upper[i] else name[i] for i in range(len(name))])
def deformat(self, name):
return name.lower()
s_fmt = sPoNGEboBNameFmt()
print(s_fmt[:5]) # [<CLean GOat (0)>, <SuBjecTIve BaT (1)>, <inVALuAbLE boNObo (2)>, <TiGht groUnDHOG (3)>, <BroWn yAK (4)>]
load your own wordlist from file using the Wordlist
class. .json
, .yml
are supported. for .txt
files or other formats it is assumed that there is one word per line.
from options import Wordlist
from name_fmt import RandomizedNameFmt
w = Wordlist("wordlists/128_singular_animals.txt")
r = RandomizedNameFmt("%animal%", animal=w)
print(list(options.wordsets.keys()))
# ['colors_16', 'singular_animals_128', 'plural_animals_128', 'rgb_24bit', 'singular_nouns_1k', 'plural_nouns_1k',
# 'adjectives_1k']
print(list(options.charsets.keys()))
# ['binary', 'octadecimal', 'decimal', 'hexadecimal', 'lowercase', 'uppercase', 'punctuation', 'whitespace',
# 'ascii_128', 'ascii_128_unescaped', 'ascii_256', 'ascii_256_unescaped', 'ascii_512', 'ascii_512_unescaped',
# 'ascii_1028', 'ascii_1028_unescaped', 'greek_lowercase', 'greek_uppercase', 'vowels_lowercase',
# 'vowels_uppercase', 'vowels', 'consonants_lowercase', 'consonants_uppercase', 'consonants', 'alphabet',
# 'alphanumeric_lowercase', 'alphanumeric_uppercase', 'alphanumeric', 'greek_alphabet']
print(list(options.wordset_aliases.keys()))
# ['colors', 'color', 'plural_animal', 'plural_animals', 'animals', 'singular_animal', 'animal', 'plural_nouns',
# 'plural_noun', 'singular_nouns', 'singular_noun', 'noun', 'adjectives', 'adjective']
print(list(options.charset_aliases.keys()))
# ['ascii_lowercase', 'az', 'ascii_uppercase', 'AZ', 'ALPHABET', 'aZ', 'english_alphabet', 'az9', 'AZ9', 'aZ9',
# '09', 'digits', 'digit', '07', 'octdigits', 'octdigit', 'hexdigits', 'hexdigit', 'hex', 'hs', 'bin', 'bs',
# 'printable', 'greek', 'GREEK', 'VOWELS', 'VOWEL', 'CONSONANTS', 'CONSONANT', 'vowel', 'consonant']
fmt = NameFmt("%greek#7% %hex#4%")
print([fmt.random_named_number() for _ in range(5)]) # [<λΥΞΓιΕΑ 82 (34166216153218)>, <πκΟΧβΣγ 3c (47605451108924)>, <ΟξημΓψΞ 47 (119835652408647)>, <Ιψεσζωπ 78 (101633973378936)>, <τΞζΕκυΨ 9b (58779657092763)>]
FAQs
Map integers to fun pseudo-random names following a custom format
We found that namednumber demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Research
Security News
Socket researchers uncover a malicious npm package posing as a tool for detecting vulnerabilities in Etherium smart contracts.
Security News
Research
A supply chain attack on Rspack's npm packages injected cryptomining malware, potentially impacting thousands of developers.
Research
Security News
Socket researchers discovered a malware campaign on npm delivering the Skuld infostealer via typosquatted packages, exposing sensitive data.