基於Java實現進制轉換工具類的示例代碼

背景

最近有個發送短信的功能,需要在短信中帶有詳情鏈接,鏈接中帶有對應信息且要有校驗功能,然而短信是按字數收費的,所以鏈接要盡可能的短。鏈接中帶有數字類型參數,就想到通過低進制轉高進制可以減少參數長度。

原理

低進制轉換到高進制的時候可能會減少位數,例如二進制是滿二進一,十進制是滿十進一。

二進制:101001101

  • 轉換為對應的四進制為:11031
  • 轉換為對應的八進制為:515
  • 轉換為對應的十進制為:333
  • 轉換為對應的十六進制為:14d
  • 轉換為對應的三十二進制為:ad

我們平常用的都是十進制的數值,就以十進制來講解下轉換方法。

十進制A轉換為N進制R

1、A除以N,商數為S1,餘數為Y1;

2、將S1除以N,商數為S2,餘數為Y2;

3、將S2除以N,商數為S3,餘數為Y3;

4、循環n次直到商數為0,餘數為Yn(Yn < N,n為下標,代表循環次數);

5、將餘數Yn作為下標取到對應的N進制的值Rn;

6、Rn,Rn-1,…,R2,R1拼接起來就得到N進制數R

用以上方法,如果是轉換為十六進制,我們帶入看下結果

十六進制值為0123456789ABCDEFA = 812, N = 16

1、812除以16,商數為50,餘數為12(對應十六進制數:C);

2、將50除以16,商數為3,餘數為2(對應十六進制數:2);

3、將3除以16,商數為0,餘數為3(對應十六進制數:3);

4、所以R = 32C

N進制R轉換為十進制A

假設R有三位數 R2R1R0,從右到左開始處理數據

S0​=R0​∗N0

S1​=R1​∗N1

S2=R2∗N2

A=S0​+S1​+S2

帶入實際數字實踐一下十六進制8F1轉換過程

S0​=1∗160 = 1 * 1 = 1

S1​=F∗161 = F + 16 = 15 * 16 = 240

S2​=8∗162 = 8 * 256 = 2048

A=1+240+2048=2289

應用

前面以十進制和十六進制轉換舉例是為瞭更好幫助大傢理解轉換的方式,在應用的過程中我們會發現十進制轉十六進制並不能減少很多數字的位數,那麼我們就可以使用三十二進制,甚至是六十二進制。

六十二進制轉換工具類實現:

/**
* 支持 import Java 標準庫 (JDK 1.8)
*/
import java.util.*;

/**
* 六十二進制轉換工具類
*/
public class Main {

  // 將字符集打亂就會帶有一點加密效果
  private static final String chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";

   private static final int scale = 62;

   public static void main(String []args) {
        Long source1 = 121231313213123L;
        String source2 = "IAvzjI19";
        System.out.println(source1 + " encode -> " + encode(source1, chars));
        System.out.println(source2 + " decode -> " + decode(source2, chars));
   }

   /**
     * 將數字轉為62進制
     *
     * @param num Long 型數字
     * @return 62進制字符串
     */
    public static String encode(long num, String chars) {
        StringBuilder sb = new StringBuilder();
        int remainder;

        while (num > scale - 1) {
            remainder = Long.valueOf(num % scale).intValue();
            sb.append(chars.charAt(remainder));
            num = num / scale;
        }

        sb.append(chars.charAt(Long.valueOf(num).intValue()));
        return sb.reverse().toString();
    }

    /**
     * 62進制字符串轉為數字
     *
     * @param str 編碼後的62進制字符串
     * @return 解碼後的 10 進制字符串
     */
    public static long decode(String str, String chars) {
        long num = 0;
        int index;
        for (int i = 0; i < str.length(); i++) {
            index = chars.indexOf(str.charAt(i));
            num += (long) (index * (Math.pow(scale, str.length() - i - 1)));
        }
        return num;
    }
}

延伸

在進制轉換的過程中,我們可以看到對應的進制有字符集,例如:十六進制字符集為0123456789ABCDEF,在轉換後得到的值假設為12,對應的就是字符集的下標位置(下標從0開始算)為12的值C。那麼低進制轉高進制除瞭縮減位數外,我們還可以打亂字符集,獲取到的值別人就不容易輕易的猜到實際值,有一點加密的效果。將十六進制字符集打亂為37AF126BCDE95480,那麼12對應的值就是5,按常規字符集推算原本的值就會得到錯誤值。

還有其他問題要註意,字符集確定後編碼瞭一些數據後,如果在修改字符集就會導致已有數據再解碼的時候出錯,無法解碼得到正確的數據,所以不要輕易修改字符集。

修改瞭字符集要做舊數據處理,或者編碼的時候加上字符集版本號,然後在解碼的時候根據版本號對應的字符集解碼。

到此這篇關於基於Java實現進制轉換工具類的示例代碼的文章就介紹到這瞭,更多相關Java進制轉換內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!

推薦閱讀: