2013-02-28 68 views
1
  • 我有其可以是一個12位的字符串或19位客戶ID也包括僅數字的原始字符串。兩種情況都是獨特的。
  • 爲了這個問題,我們假設我們正在處理一個12位數的字符串,如果您提出了一個解決方案,那麼它也必須適合19位數的情況。
  • 我們的客戶希望我們創建一個第二個唯一的字符串,其長度需要爲11個字符(無論原始字符串是12位數字還是19位數字符號);這個唯一的字符串/ ID應該包含字母數字字符,其中'alpha'表示所有字母都可以成爲它的一部分;即「參與」字符僅爲數字的解決方案+從「a」到「e」的小寫字母是不夠的,因爲當使用所有較低的字母時,它給我們較少的選項。
  • 請注意,我不需要加密,但是需要一個UNIQUE功能。
  • 我將不勝感激任何幫助,首選的例子或鏈接的例子。
  • 如果有人知道解決此類問題的第三方軟件包,請留下鏈接。 在此先感謝!你可以嘗試
+0

很抱歉關於獨特的誤解;我編輯了我原來的問題......關於你的答案,我無法理解這是如何將原始長度降低到11.在此先感謝... – boomboom 2013-02-28 08:03:22

+0

那麼,還有其他建議嗎?我不介意爲此問題提供第三方JAR /軟件包。在此先感謝... – boomboom 2013-02-28 08:20:29

+0

11個字符串是否需要可讀或可以包含任何字符?最後11位數字和「正常」字母(小號和大號)可以代表19位數字,因此可以完成((26 + 26 + 10)** 11) – assylias 2013-02-28 08:21:59

回答

1

的一種方式。

讓你的12位二進制的介紹,這應該能夠通過5個字節來表示。使用base64編碼它,它應該能夠用9個字母數字字符表示。 (確定...的base64也包含一些非字母數字字符...:P)

(如果你有困難,使其成爲5字節表示,打破了12位到3組,每組4個數字,每個由2個字節表示應該也可以工作)

搜索Base64和得到一些理解它,那麼你就可以實現類似的方式自己的編碼方法。


添加一些代碼: (未測試,只是給ü的想法上,它看起來像)

String originalId= "123456789012"; 

String resultString = new String(Base64.encodeBase64(new BigInteger(originalId).toByteArray()); 
+0

我編輯了我的問題;我得到的反饋意見是不夠清楚的 - 請再看一遍,在此先感謝... – boomboom 2013-02-28 11:51:13

+0

這個想法是一樣的。你需要的是改變以BASE-64(或另一個問題中提出的BASE-62,如果你需要嚴格的字母數字)形式呈現你的19位BASE-10整數值。我建議BASE-64的原因是因爲它內置且快速。 – 2013-03-01 02:55:15

0

原來的答案建議使用的BigInteger與36爲基數,但不會足夠19位數字。

我不知道是否有庫轉換到/從基地62,但低於人爲的例子給你的你如何能做到這一點的想法。輸出是:

originalId = 999999999999999999
NEWID = bUI6zOLZTrh
retrieveOriginalId = 999999999999999999

使用基62的理由是如下:

  • 如果原始數是獨一無二的,新的也將是獨一無二的,因爲它們確實是相同的數字(即有一對一的關係)
  • 你可以代表N^11基數N中的11個字符的數字(例如,基數爲10,11位數字可以在0和10^11之間或1000億)
  • 最大的19位數字(以10爲底數)是10^19 - 1
  • N = 62,您有62^11 = 5 * 10^19的可能性,大於10^19,因此可以表示任何19位數字。實際上使用base 54就足夠了。

示例代碼(從BigInteger和龍類啓發算法 - 要添加異常處理):

class Base62 { 

    private static final BigInteger RADIX = BigInteger.valueOf(62); 
    private static final char[] DIGITS = { 
     '0', '1', '2', '3', '4', '5', 
     '6', '7', '8', '9', 'a', 'b', 
     'c', 'd', 'e', 'f', 'g', 'h', 
     'i', 'j', 'k', 'l', 'm', 'n', 
     'o', 'p', 'q', 'r', 's', 't', 
     'u', 'v', 'w', 'x', 'y', 'z', 
     'A', 'B', 'C', 'D', 'E', 'F', 
     'G', 'H', 'I', 'J', 'K', 'L', 
     'M', 'N', 'O', 'P', 'Q', 'R', 
     'S', 'T', 'U', 'V', 'W', 'X', 
     'Y', 'Z' 
    }; 

    public static void main(String[] args) throws IOException { 
     String originalId = "999999999999999999"; 
     System.out.println("originalId = " + originalId); 

     String newId = getBase62From10(originalId); 
     System.out.println("newId = " + newId); 

     String retrieveOriginalId = getBase10From62(newId); 
     System.out.println("retrieveOriginalId = " + retrieveOriginalId); 
    } 

    /** 
    * 
    * @param number a positive number in base 10 
    * 
    * @return the same number, in base 62 
    */ 
    public static String getBase62From10(String number) { 
     char[] buf = new char[number.length()]; 
     int charPos = number.length() - 1; 

     BigInteger i = new BigInteger(number); 
     BigInteger radix = BigInteger.valueOf(62); 

     while (i.compareTo(radix) >= 0) { 
      buf[charPos--] = DIGITS[i.mod(radix).intValue()]; 
      i = i.divide(radix); 
     } 
     buf[charPos] = DIGITS[i.intValue()]; 

     return new String(buf, charPos, (number.length() - charPos)); 
    } 

    /** 
    * 
    * @param number a positive number in base 62 
    * 
    * @return the same number, in base 10 
    */ 
    public static String getBase10From62(String number) { 
     BigInteger value = BigInteger.ZERO; 
     for (char c : number.toCharArray()) { 
      value = value.multiply(RADIX); 
      if ('0' <= c && c <= '9') { 
       value = value.add(BigInteger.valueOf(c - '0')); 
      } 
      if ('a' <= c && c <= 'z') { 
       value = value.add(BigInteger.valueOf(c - 'a' + 10)); 
      } 
      if ('A' <= c && c <= 'Z') { 
       value = value.add(BigInteger.valueOf(c - 'A' + 36)); 
      } 
     } 
     return value.toString(); 
    } 
} 
+0

我需要澄清: - 您建議36基數,因爲它是10位數字+26個小寫字母 - 我說得對嗎? - 這確保了一個獨特的字符串? - 你能解釋一下如何製作一個11字符的字符串嗎?我怎麼知道基數應該是什麼? 我開始使用較低的基數,當我到達15時,它給了我一個11個字符的字符串。 在這種情況下,這意味着使用的字符將是0-9和a-e? 在這種情況下,它確保唯一性嗎? 在此先感謝... – boomboom 2013-02-28 08:55:00

+0

@AsafLevy我已添加更多詳細信息。 (i)最大基數爲36,僅使用數字(0至9)和小型上限(a至z)(ii)較低基數將使用較少字母(iii)如果您的原始ID是唯一的,則保證唯一性 – assylias 2013-02-28 09:25:58

+0

I還添加了代碼以轉換回原始ID。 – assylias 2013-02-28 09:28:02

相關問題