目前我有一堆与数字相关联的名称,例如:
Joe Bloggs - 17
约翰史密斯 - 23
保罗史密斯 - 24
Joe Bloggs - 32
使用姓名和号码,我希望生成由4个数字组成的随机/唯一ID,该ID也以初始号码结尾。
因此,例如,Joe Bloggs和17会创建一些随机/独特的东西,如:xxxx17。
bash有可能吗?用其他语言会更好吗?
这将用于基于debian和darwin的系统。
答案 0 :(得分:1)
除非有两个Joe Bloggs 17,否则每个名称在添加号码后都会变得独一无二。在您的情况下,有两个Joe Bloggs,一个有17和32个。将它们组合在一起,您就具有唯一性" Joe Bloggs 17"和#34; Joe Bloggs 32"不一样。使用它,您可以简单地为每个名称+数字对分配一个数字,并在关联数组(字典)中记住该数字。不需要随机。当您找到字体中已有的名称时,只需继续增加数字,然后将新数字与名称相关联。如果唯一性是唯一的目标,那么你就可以容纳10,000人。
Python是一种很好的语言,但您也可以在BASH中创建关联数组。
答案 1 :(得分:1)
不可能确保4位哈希(校验和)对于一组10个字符的长名称是唯一的。
作为替代方案,您可以尝试
file="./somefile"
paste -d"\0\n" <(seq -f "%04g" 9999 | sort -R | head -$(grep -c '' "$file")) <(grep -oP '\d+' "$file")
为了更好的可读性
paste -d"\0\n" <(
seq -f "%04g" 9999 | gsort -R | head -$(grep -c '' "$file")
) <(
grep -oP '\d+' "$file"
)
为您的输入产生如下内容:
010817
161523
748024
269032
所有行的格式均为RRRRXX
,其中:
RRRR
是一个保证唯一且随机的数字(范围从0001
到9999
)XX
是您输入的数字分解:
seq
生成9999个4位数字(ofc,每个数字都是唯一的)sort -R
按随机顺序对行进行排序(根据哈希值,得到唯一的随机数)head
- 从随机列表中仅显示前N行,其中N是文件中的行数,grep -c ''
计算(优于wc -l
)grep -oP
过滤了文件中的数字paste
将两个输入组合到最终输出<(..) <(..)
是流程替换答案 2 :(得分:0)
使用$(date +%N)
生成的随机字符串,然后选择4位数作为新ID中字符的第一个数字,您可以非常接近完成所需的操作。如果您想要更靠近的ID,或者从字符串的中间部分获得更多随机性,您可以从头开始选择。选择随机4之后,只需跟踪数组中使用的数据,并在分配每个新ID时检查数组。对于10,000个左右的ID,此开销可忽略不计:
#!/bin/bash
declare -a used4=0 # array to hold IDs you have assigned
declare -i dupid=0 # a flag to prompt regeneration in case of a dup
while read -r line || [ -n "$line" ]; do
name=${line% -*}
id2=${line##* }
while [ $dupid -eq 0 ]; do
ns=$(date +%N) # fill variable with nanoseconds
fouri=${ns:4:4} # take 4 integers (mid 4 for better randomness)
# test for duplicate (this is BASH only test - use loop if portability needed)
[[ "$fouri" =~ "${used4[@]}" ]] && continue
newid="${fouri}${id2}" # contatinate 4ints + orig 2 digit id
used4+=( "$fouri" ) # add 4ints to used4 array
dupid=1
done
dupid=0 # reset flag
printf "%s => %s\n" "$line" "$newid"
done<"$1"
<强>输出:强>
$ bash fourid.sh dat/nameid.dat
Joe Bloggs - 17 => 762117
John Smith - 23 => 603623
Paul Smith - 24 => 210424
Joe Bloggs - 32 => 504732