2011-05-28 34 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; 
    } 
} 

//編輯:

只是指出來,這是一個編碼...沒有加密