是否可以將用戶的ID#編碼爲文本值?PHP編碼方法
例如,如果用戶編號是「50624」,纔有可能將其轉換爲7個字符的文本價值,像「DEGXCVG」?
如果我使用MD5這個功能我得到16字節的哈希值。 結果值不應超過7或8個字符。
編輯: 我想,每個用戶從身份證號碼獲得一個不同的文本代碼。
是否可以將用戶的ID#編碼爲文本值?PHP編碼方法
例如,如果用戶編號是「50624」,纔有可能將其轉換爲7個字符的文本價值,像「DEGXCVG」?
如果我使用MD5這個功能我得到16字節的哈希值。 結果值不應超過7或8個字符。
編輯: 我想,每個用戶從身份證號碼獲得一個不同的文本代碼。
如果散列函數如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));
}
什麼是你想用這個來完成?
首先MD5不是「加密」,它是單向散列函數。它不可逆轉。如果這對你是好的,爲什麼不簡單地散列你的ID,然後從散列中取7-8個字符?你可以MD5你的ID,然後取得生成的MD5的前8個字符。
如果遮擋足夠好,轉換數base62置換其位之後。
我想你可以設計自己的加密方法,或採取MD5哈希值的一部分。
順便說一句,加密整數的方式已經在下面的帖子中討論過了。
你在找什麼被稱爲基本轉換...您的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;
}
}
//編輯:
只是指出來,這是一個編碼...沒有加密
輸入值的值範圍是多少? – Gumbo 2011-05-28 12:28:53
值是從0到100.000 + – Sergio 2011-05-28 12:42:36
所以它是無符號的32位整數值? – Gumbo 2011-05-28 12:57:32