2011-05-28 103 views
0

是否可以将用户的ID#编码为文本值?PHP编码方法

例如,如果用户编号是“50624”,才有可能将其转换为7个字符的文本价值,像“DEGXCVG”?

如果我使用MD5这个功能我得到16字节的哈希值。 结果值不应超过7或8个字符。

编辑: 我想,每个用户从身份证号码获得一个不同的文本代码。

+0

输入值的值范围是多少? – Gumbo 2011-05-28 12:28:53

+0

值是从0到100.000 + – Sergio 2011-05-28 12:42:36

+0

所以它是无符号的32位整数值? – Gumbo 2011-05-28 12:57:32

回答

1

如果散列函数如MD5可以用来代替加密,你可以尝试crc32()而是产生较短(但具有更高的碰撞机会)字符串。


如果你只关心编码,可以做些简单:

function encode($id) { 
    $id_str = (string) $id; 
    $offset = rand(0, 9); 
    $encoded = chr(79 + $offset); 
    for ($i = 0, $len = strlen($id_str); $i < $len; ++$i) { 
    $encoded .= chr(65 + $id_str[$i] + $offset); 
    } 
    return $encoded; 
} 

function decode($encoded) { 
    $offset = ord($encoded[0]) - 79; 
    $encoded = substr($encoded, 1); 
    for ($i = 0, $len = strlen($encoded); $i < $len; ++$i) { 
    $encoded[$i] = ord($encoded[$i]) - $offset - 65; 
    } 
    return (int) $encoded; 
} 

例子:

var_dump(encode(50624)); // string(6) "TKFLHJ" 

加密版本:

define('CRYPTO_KEY', 'Secret key'); 

function encrypt($id) { 
    return base64_encode(mcrypt_encrypt(MCRYPT_BLOWFISH, CRYPTO_KEY, (string) $id, MCRYPT_MODE_ECB)); 
} 

function decrypt($encrypted) { 
    return (int) base64_decode(mcrypt_decrypt(MCRYPT_BLOWFISH, CRYPTO_KEY, $encrypted, MCRYPT_MODE_ECB)); 
} 
+0

@rdineiu - 这是很好的解决方案。但我得到了一些奇怪的人物。可能是什么问题? – Sergio 2011-05-28 12:36:08

+0

@Sergio,它是加密的字符串。使用'base64_encode()'或'urlencode()'来编码。查看示例的最后部分。 – rid 2011-05-28 12:36:55

+0

@rdineiu - 我做到了,但我得到了varchar值。我需要没有数字的结果值。 – Sergio 2011-05-28 12:41:59

1

什么是你想用这个来完成?

首先MD5不是“加密”,它是单向散列函数。它不可逆转。如果这对你是好的,为什么不简单地散列你的ID,然后从散列中取7-8个字符?你可以MD5你的ID,然后取得生成的MD5的前8个字符。

+0

在这种情况下,如果我使用哈希中的前7个字符,那么其他一些用户具有相同哈希码的机会是多少?我希望每个用户都有一个从ID号码获得的不同文本代码。 – Sergio 2011-05-28 12:20:22

+0

2个用户具有相同的价值是非常不可能但并非不可能的。将int转换为十六进制字符串可能会更好。无论何时,当你将某物投射到一个固定的宽度时,你必然会有一个有限数量的可能输出,所以没有办法将无限数量的输入映射到有限数量的输出而没有重复值(碰撞)。 – defines 2011-05-28 12:22:45

0

如果遮挡足够好,转换数base62置换其位之后。

0

我想你可以设计自己的加密方法,或采取MD5哈希值的一部分。
顺便说一句,加密整数的方式已经在下面的帖子中讨论过了。

Way to encrypt a single int

2

试着改变整数到使用​​

一个十六进制值,反正如果u能说明您的情况更加清晰,我们将能为客户提供最佳的解决方案

+1

这不会被加密,但只能编码。 – Gumbo 2011-05-28 12:23:11

+0

你说得对,对不起。不加密,编码。 – Sergio 2011-05-28 12:27:15

+0

@gumbo是的,因为我不知道他的确切要求,我只是建议一个编码解决方案。谢谢你的评论。 :) – Vijay 2011-05-28 12:27:41

1

你在找什么被称为基本转换...您的ID是基数为10的数字,数字从0到9代表该基数的数字。其他常用的基数是2(二进制),16(十六进制)或64(通常称为基本64编码),但如果你喜欢,也可以采用其他基数。

我写了一个略显一般基地,在C#变换代码(UINT到任何基础线,反之亦然)......不应该是很难将它移植到PHP:

static void Main(string[] args) 
{ 
    foreach (var item in UintToOtherBase(0xDEADBEEF, "01").Reverse()) 
    { 
     Console.Write(item); 
    } 
    Console.WriteLine(); 
    Console.WriteLine(OtherBaseToInt(UintToOtherBase(0xDEADBEEF, "01"), "01").ToString("X")); 
    Console.WriteLine(UintToOtherBase(0xDEADBEEF, "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")); 
} 

public static string UintToOtherBase(uint input, string newBaseDigits) 
{ 
    char[] uniqueDigits = newBaseDigits.ToCharArray().Distinct().ToArray(); 
    uint newBase = (uint)uniqueDigits.Length; 
    if (newBase < 2) 
    { 
     throw new ArgumentException("otherBaseDigits has to contain at least 2 unique chars"); 
    } 
    else 
    { 
     StringBuilder sb = new StringBuilder(); 
     while (input != 0) 
     { 
      uint digit = input % newBase; 
      sb.Append(uniqueDigits[digit]); 
      input /= newBase; 
     } 
     return sb.ToString(); 
    } 
} 
public static uint OtherBaseToInt(string input, string otherBaseDigits) 
{ 
    string uniqueDigits = new String(otherBaseDigits.ToCharArray().Distinct().ToArray()); 
    int otherBase = uniqueDigits.Length; 
    if (otherBase < 2) 
    { 
     throw new ArgumentException("otherBaseDigits has to contain at least 2 unique chars"); 
    } 
    else if (input.ToCharArray().Any(x => !uniqueDigits.Contains(x))) 
    { 
     throw new ArgumentException("an input char was not found in otherBaseDigits"); 
    } 
    else 
    { 
     uint result = 0; 
     int pow = 0; 
     foreach (var c in input) 
     { 
      result += (uint)uniqueDigits.IndexOf(c) * (uint)Math.Pow(otherBase, pow++); 
     } 
     return result; 
    } 
} 

//编辑:

只是指出来,这是一个编码...没有加密