從0到M的整數將映射到由某個字母組成的n個字符的代碼。 棘手的部分是代碼應該看起來是僞隨機的,非順序的。像這樣:散列的雙目模擬
0 BX07SU
1 TYN9RQ
2 QZ1697
我認爲這是一個常見的知識片,我錯過了。他們如何將這種類型的函數稱爲f(i) = s
- 將整數映射爲僞隨機字符串,並且在一定範圍內沒有碰撞?
反向函數也會很好:h(s) = i
,能夠將有效字符串'解碼'爲一個整數,或者確定提供的字符串是無效的。
從0到M的整數將映射到由某個字母組成的n個字符的代碼。 棘手的部分是代碼應該看起來是僞隨機的,非順序的。像這樣:散列的雙目模擬
0 BX07SU
1 TYN9RQ
2 QZ1697
我認爲這是一個常見的知識片,我錯過了。他們如何將這種類型的函數稱爲f(i) = s
- 將整數映射爲僞隨機字符串,並且在一定範圍內沒有碰撞?
反向函數也會很好:h(s) = i
,能夠將有效字符串'解碼'爲一個整數,或者確定提供的字符串是無效的。
對於小型M
@ user1494736是正確的:只需創建一個恰好是雙射的查找表,並根據需要定製它。對於大的M
存儲表變得不切實際;我們需要一個算法來計算映射。你提到我們不需要強大的密碼學;這使我們能夠選擇比標準密碼更重量輕的東西。也就是說,它們非常快,我希望你可以輕鬆地使用第三方庫。但假設你出於某種原因避免這種情況。
讓窮人的密碼的一種方法是在你的明文上使用xor
常量(改變漢明權重),然後應用一點排列(以破壞局部性)。這兩個步驟都是可逆的。這聽起來像你想要顯示你的密碼字母爲ASCII。所以,我們可能需要最終的可逆轉換(一個加法)來確保密碼值是可打印的。您提到的M
可能大到幾百萬。所以,讓我們把你的明文字母(以及密文字母)作爲32位值。找到一個隨機的32位值到xor
很容易。比特排列怎麼樣?
幾百萬個明文字母翻譯成約爲22
或23
位寬的每個字母;這至少會在每個明文字母中清除至少8
(邏輯)高位。置換可以利用這一點來幫助確保密文字節在ASCII可打印範圍內。通過將這個高位明文字節發送到四個密碼字節中的每一個的高兩位,我們確保每個密碼字節取值0
到63
。然後,最後一步可以添加48
以使範圍48
到111
完全位於ASCII可打印範圍內。
耍過這種觀察,我們可以設想我們的明文字母爲4x4
網格位對的,使我們的置換該網格的旋轉:
Plain
A B C D byte 3 (the high byte, expected to be all 0)
E F G H byte 2
I J K L byte 1
M N O P byte 0
Cipher
D H L P byte 3
C G K O byte 2
B F J N byte 1
A E I M byte 0
或者換一種說法:
Byte 3 2 1 0
Plain ABCD EFGH IJKL MNOP
Cipher DHLP CGKO BFJN AEIM
請注意,每個密文字節中都會出現一段每個明文字節:這將確保編碼「看起來像是隨機的」。
對於related question我發佈了一個答案。在你的情況下,你需要一個額外的數學函數將你的號碼映射到一個不同的數字(也許使用一個簡單的散列函數),並使用這個數字編碼到一個基數爲36的數字。
獲得單向雙射散列的最簡單方法是使用普通的舊CRC。對於32/64位是可逆的,但我從來沒有看到代碼做相反的事情。
「僞隨機的,非順序的」是指反函數應該難以計算,還是僅僅是一組輸入中的局部性在輸出中被破壞? – phs 2012-07-29 23:00:49
@phs,這個函數並不期望加密強度,目的是純粹的美學。所以,「第二選擇」。 – Serge 2012-07-30 11:49:51
'M'的規模有多大? 26,也許還是數千?百萬? – phs 2012-08-03 04:32:36