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