基于Java實現(xiàn)進制轉換工具類的示例代碼
背景
最近有個發(fā)送短信的功能,需要在短信中帶有詳情鏈接,鏈接中帶有對應信息且要有校驗功能,然而短信是按字數(shù)收費的,所以鏈接要盡可能的短。鏈接中帶有數(shù)字類型參數(shù),就想到通過低進制轉高進制可以減少參數(shù)長度。
原理
低進制轉換到高進制的時候可能會減少位數(shù),例如二進制是滿二進一,十進制是滿十進一。
二進制:101001101
- 轉換為對應的四進制為:11031
- 轉換為對應的八進制為:515
- 轉換為對應的十進制為:333
- 轉換為對應的十六進制為:14d
- 轉換為對應的三十二進制為:ad
我們平常用的都是十進制的數(shù)值,就以十進制來講解下轉換方法。
十進制A轉換為N進制R
1、A除以N,商數(shù)為S1,余數(shù)為Y1;
2、將S1除以N,商數(shù)為S2,余數(shù)為Y2;
3、將S2除以N,商數(shù)為S3,余數(shù)為Y3;
4、循環(huán)n次直到商數(shù)為0,余數(shù)為Yn(Yn < N,n為下標,代表循環(huán)次數(shù));
5、將余數(shù)Yn作為下標取到對應的N進制的值Rn;
6、Rn,Rn-1,...,R2,R1拼接起來就得到N進制數(shù)R
用以上方法,如果是轉換為十六進制,我們帶入看下結果
十六進制值為0123456789ABCDEFA = 812, N = 16
1、812除以16,商數(shù)為50,余數(shù)為12(對應十六進制數(shù):C);
2、將50除以16,商數(shù)為3,余數(shù)為2(對應十六進制數(shù):2);
3、將3除以16,商數(shù)為0,余數(shù)為3(對應十六進制數(shù):3);
4、所以R = 32C
N進制R轉換為十進制A
假設R有三位數(shù) R2R1R0,從右到左開始處理數(shù)據(jù)
S0?=R0?∗N0
S1?=R1?∗N1
S2=R2∗N2
A=S0?+S1?+S2?
帶入實際數(shù)字實踐一下十六進制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
應用
前面以十進制和十六進制轉換舉例是為了更好幫助大家理解轉換的方式,在應用的過程中我們會發(fā)現(xiàn)十進制轉十六進制并不能減少很多數(shù)字的位數(shù),那么我們就可以使用三十二進制,甚至是六十二進制。
六十二進制轉換工具類實現(xiàn):
/**
* 支持 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));
}
/**
* 將數(shù)字轉為62進制
*
* @param num Long 型數(shù)字
* @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進制字符串轉為數(shù)字
*
* @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。那么低進制轉高進制除了縮減位數(shù)外,我們還可以打亂字符集,獲取到的值別人就不容易輕易的猜到實際值,有一點加密的效果。將十六進制字符集打亂為37AF126BCDE95480,那么12對應的值就是5,按常規(guī)字符集推算原本的值就會得到錯誤值。
還有其他問題要注意,字符集確定后編碼了一些數(shù)據(jù)后,如果在修改字符集就會導致已有數(shù)據(jù)再解碼的時候出錯,無法解碼得到正確的數(shù)據(jù),所以不要輕易修改字符集。
修改了字符集要做舊數(shù)據(jù)處理,或者編碼的時候加上字符集版本號,然后在解碼的時候根據(jù)版本號對應的字符集解碼。
到此這篇關于基于Java實現(xiàn)進制轉換工具類的示例代碼的文章就介紹到這了,更多相關Java進制轉換內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
SpringCloud如何利用Feign訪問外部http請求
這篇文章主要介紹了SpringCloud如何利用Feign訪問外部http請求,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-03-03
Mybatis批量插入數(shù)據(jù)返回主鍵的實現(xiàn)
這篇文章主要介紹了Mybatis批量插入數(shù)據(jù)返回主鍵的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2020-01-01
mybatis動態(tài)新增(insert)和修改(update)方式
這篇文章主要介紹了mybatis動態(tài)新增(insert)和修改(update)方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-05-05
Spring超詳細講解創(chuàng)建BeanDefinition流程
Spring在初始化過程中,將xml中定義的對象解析到了BeanDefinition對象中,我們有必要了解一下BeanDefinition的內部結構,有助于我們理解Spring的初始化流程2022-06-06
java ThreadLocal線程局部變量常用方法使用場景示例詳解
這篇文章主要介紹了為大家java ThreadLocal線程局部變量常用方法使用場景示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-07-07
idea創(chuàng)建的idea項目時springframework出現(xiàn)紅色的原因和解決方法
當使用 IntelliJ IDEA 創(chuàng)建 Spring Framework 項目時,springframework 出現(xiàn)紅色可能是因為相關的 Spring Framework 依賴沒有正確加載或項目的配置有問題,本文給大家介紹了一些常見的原因和解決方法,需要的朋友可以參考下2023-09-09
Java While循環(huán) do-while循環(huán)用法
循環(huán)語句就是讓計算機根據(jù)條件做循環(huán)計算,在條件滿足時繼續(xù)循環(huán),條件不滿足時退出循環(huán),需要的朋友可以參考下2020-11-11

