2011-06-09 575 views
1

我有一個要求將「ABC123」等6個字符的字符串縮短爲唯一的4個字符的字符串。它必須是可重複的,以便輸入字符串將始終生成相同的輸出字符串。有沒有人有任何理想如何做到這一點?縮短Java中的字符串

+7

我不理解你的要求。你想要一個從6個字符串到4個字符串的唯一映射嗎?這不可能是1-1,因爲你映射的是你映射的子集。 – 2011-06-09 21:35:41

回答

8

不可能從6個字符的字符串到4個字符的字符串進行完全獨特的映射。這是一個簡單的hash function的例子。因爲範圍空間比域空間小,所以你必定會有一些散列collisions。您可以嘗試根據要接受的數據類型來最小化碰撞次數,但最終不可能將每6個字符的字符串映射到一個唯一的4個字符的字符串,您將用盡4個字符的字符串。

3

你需要對輸入字符串進行一些限制,否則數學將不可避免地咬你。

例如,假設您知道它只包含大寫字母和數字。因此,有36^6個可能的輸入字符串。

結果需要有較少的限制,例如,你允許216個不同的字符(打印擴展ascii或類似的東西)。

純粹的巧合,216^4 = 36^6,所以你需要的是一個映射。這很簡單,只需使用算法將數字表示從一個基數轉換爲另一個基數即可。

1

不確定這是可以做到的,因爲我敢打賭有一些商業限制(就像用戶必須能夠輸入密鑰一樣)。

這個想法是將這個值「散列」到更少的地方。這需要一個足夠大的字符集來處理所有組合。我們假設原始密鑰不區分大小寫,你有26 + 10 = 32,然後提升到第6個唯一組合(2,176,782,336個獨特組合)。爲了只匹配4個字符,必須使用216個唯一字符的字符集,因爲216^6是2,176,782,336,或者第一個數字會比具有數字的不區分大小寫鍵的組合多出4個字符。 (案例不重要,加上數字只會把你帶到62)。

如果我們把美國的標準鍵盤,我們有26個字母X2箱子= 52個 10個號碼上的數字鍵 10特殊字符 11等特殊字符鍵* 2 = 22

這是94個獨特的字符,或者不到一半的唯一身份只需要將大小寫不敏感的6位數字代碼轉換爲4位數字。現在,在Klingon星球上,鍵盤更大...... ;-)

如果鍵不區分大小寫,您的字符集必須擴展爲489個獨特的字符以適應4位數的「散列」。哎喲!

0

假設:輸入字符串只能包含ASCII十進制值低於128的字符......否則,正如其他人所說,這不會工作。

public class Foo { 

    public static int crunch(String str) { 
     int y = 0; 
     int limit = str.length() > 6 ? 6 : str.length(); 
     for (int i = 0; i < limit; ++i) { 
      y += str.charAt(i) * (limit - i); 
     } 
     return y; 
    } 

    public static void main(String[] args) { 
     String[] words = new String[]{ 
      "abcdef", "acdefb", "fedcba", "}}}}}}", "ZZZZZZ", "123", "!" 
     }; 

     for (int idx = 0; idx < words.length; ++idx) { 
      System.out.printf("in=%-6s out=%04d\n", 
       words[idx], crunch(words[idx])); 
     } 
    } 
} 

生成:

in=abcdef out=2072 
in=acdefb out=2082 
in=fedcba out=2107 
in=}}}}}} out=2625 
in=ZZZZZZ out=1890 
in= 123 out=0298 
in=  ! out=0033 
0

你必須做出關於值的範圍的假設字符可以有,當是一個可以接受的編碼字符。有很多方法可以做到這一點。根據您的假設,您可以將字符串打包爲1,2,3,4或5個字符。

一個簡單的例子會給你4個字符是假設最後三個字母是一個數字。

public static String pack(String text) { 
    return text.substring(0, 3) + (char) Integer.parseInt(text.substring(3)); 
} 

public static String unpack(String text) { 
    return text.substring(0, 3) + ("" + (1000 + text.charAt(3))).substring(1); 
} 

public static void main(String[] args) throws IOException { 
    String text = "ABC123"; 
    String packed = pack(text); 
    System.out.println("packed length= " + packed.length()); 
    String unpacked = unpack(packed); 
    System.out.println("unpacked= '" + unpacked + '\''); 

} 

打印

packed length= 4 
unpacked= 'ABC123'