从bash中的名称生成ID号

时间:2014-09-01 22:07:57

标签: bash random

目前我有一堆与数字相关联的名称,例如:

Joe Bloggs - 17
约翰史密斯 - 23
保罗史密斯 - 24
Joe Bloggs - 32

使用姓名和号码,我希望生成由4个数字组成的随机/唯一ID,该ID也以初始号码结尾。

因此,例如,Joe Bloggs和17会创建一些随机/独特的东西,如:xxxx17。

bash有可能吗?用其他语言会更好吗?
这将用于基于debian和darwin的系统。

3 个答案:

答案 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是一个保证唯一且随机的数字(范围从00019999
  • 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