将整数映射到用户名

时间:2010-01-20 19:07:30

标签: mapping username userid

一位客户和我正在集思广益,从数字用户ID(由数据库生成)生成用户名。关键要求是用户名是唯一的。

最明显的解决方案是将用户名设置为等于用户ID。但一个重要的要求是用户名不是“明显顺序” - 因此当用户ID可能达到4000,4001,4002,4003时,客户端不希望用户看到用户名中的进展,即使这些最终将使用数字。

用户名的长度也应该是紧凑的 - 也就是说,长度不会增长,直到用户ID达到长度增长所需的点。

有什么建议吗?

编辑: 大多数答案都认为机制的安全性很重要 - 事实并非如此。客户只是不希望显而易见的是谁是用户名的“高级”成员。

用户名的主要目标是易于记忆,因此长哈希不太好。

字母数字是可以的,但客户端担心分配可能“坏”的用户名。 fpq321没问题,ass123不行。这些将是用户的公共“处理”。

7 个答案:

答案 0 :(得分:4)

我倾向于选择词汇表中的随机词+随机数。冲洗&如果你没有独特的话,重复一遍。碰撞很少见,特别是如果你使用两个相当大的单词列表。例如:

Wordlist A 名词,例如

  • 探戈
  • 布拉沃
  • α

Wordlist B 形容词或动词

  • 海量
  • 光辉
  • 恶心

因此,一些例子可能是“令人厌恶的Tango1208”,“GloriousAlpha1912”,“MassiveAlpha15”等。这种方法的优点是用户可以更容易记住单词。只要你保持数字低,它们也不会造成问题,远远少于16个字母数字字符。

我知道这不满足长度/增长要求,但这样做可以深入了解序列的线性度(范围为1,000)。因此,似乎可以通过1,000次强力尝试来获得ID#。

答案 1 :(得分:1)

您是否考虑过使用GUID?这很长,但你不会重叠。或者MD5哈希怎么样?

答案 2 :(得分:1)

如果他们不必友好阅读,您可以使用MD5或类似的哈希。这总是输出相同的长度,“从不”有任何碰撞。当然,我松散地使用“从不”这个词。

但是,应该可以满足您的需求。

答案 3 :(得分:1)

一种可能的方法是在用户ID上运行哈希函数。您可以使用顺序探测。例如,如果用户ID哈希值为300但已经在使用中,则接下来检查301,然后检查302,然后检查303.

答案 4 :(得分:1)

您可以稍微转换整数 - 重新排列其字节 - 将字节1替换为字节3,将字节2替换为字节4等,并将其用作用户名。虽然这并不一定保持紧凑(因为它确实从小数字中得到更大的数字)。

例如:

BYTE b1 = i&0xFF;
BYTE b2 = (i>>8)&0xFF;
BYTE b3 = (i>>16)&0xFF;
BYTE b4 = (i>>24)&0xFF;

int nTransformed = (b2<<24) | (b1<<16) | (b3<<8) | b4;

它使它们保持独特但不明显是连续的。

答案 5 :(得分:1)

如果您希望将用户名保持为用户ID的简短,则可以执行以下操作: (它只是用[字符] [符号] [其他数字]替换数字)

<?php
// function generates (always the same) username from an ID
function get_username($id){
    $i=0;
    $return=null;
    // define some strings used to generate the usernames (must be 10 chars long)
    $string1=str_split('abcdefghij');
    $string2=str_split('KLMNOPQRST');
    $string3=str_split('3274190258');
    $string4=str_split('ANYSTRINGY');
    $string5=str_split('TENCHARSLO');
    if($splitted=str_split($id)){ // split username
        foreach($splitted as $i => $char){ // loop trough each number of uses_id
            if($i==0) $return .= $string1[(intval($char))]; // 1st char is picked from $sting1
            elseif($i==1) $return .= $string2[(intval($char))];
            elseif($i==2) $return .= $string3[(intval($char))];
            elseif($i==3) $return .= $string4[(intval($char))];
            else $return .= $string5[(intval($char))]; // from 5 chars, pick from sting 5
        }
    }
    return (!empty($return))?$return:false; // return username or false if argument is empty
}
get_username(45879);
?>

答案 6 :(得分:0)

此问题的常见解决方案是让用户选择自己的用户名,然后将其与用作主键的用户ID相关联。