概述
36進(jìn)制:使用 [0-9,a-z]
描述白指,逢36進(jìn)一,即稱(chēng)之為36進(jìn)制
var num2char = "0123456789abcdefghijklmnopqrstuvwxyz"
典型應(yīng)用:汽車(chē)號(hào)碼牌,比如: 京 B0540Z乾翔;順序生成序號(hào)等
進(jìn)制轉(zhuǎn)換規(guī)則參考16進(jìn)制與10進(jìn)制轉(zhuǎn)換,大體如下:
- 10進(jìn)制轉(zhuǎn)36進(jìn)制施戴,用10進(jìn)制數(shù)除了36反浓,取余數(shù)得最低1位,然后把商繼續(xù)除36赞哗,得第二位雷则,直到商為0。舉例:
- 126110
- 1261 除 36 余數(shù) 35 (對(duì)應(yīng) Z)肪笋,商 1
- 1 除 36 余數(shù) 1 (對(duì)應(yīng)1)月劈,商 0 結(jié)束
- 得到 (Z1)36
- 36進(jìn)制轉(zhuǎn)10進(jìn)制,36進(jìn)制數(shù)按權(quán)展開(kāi)藤乙,從右邊第一個(gè)數(shù)開(kāi)始猜揪,每一個(gè)乘以16的n次方,n從0開(kāi)始坛梁,每次遞增1湿右,然后得出來(lái)的每個(gè)數(shù)相加即是十進(jìn)制數(shù)。舉例:
- (Z1)36 = 35 * 361+ 1 * 360 = 126110
- (ABC)36 = 10 * 362 + 11 * 361+ 12 * 360 = 1336810
golang 程序?qū)崿F(xiàn):
編碼:
// 10進(jìn)制數(shù)轉(zhuǎn)換 n 表示進(jìn)制罚勾, 16 or 36
func NumToBHex(num, n int) string {
num_str := ""
for num != 0 {
yu := num % n
num_str = string(num2char[yu]) + num_str
num = num / n
}
return strings.ToUpper(num_str)
}
解碼
// 36進(jìn)制數(shù)轉(zhuǎn)換 n 表示進(jìn)制毅人, 16 or 36
func BHex2Num(str string, n int) int {
str = strings.ToLower(str)
v := 0.0
length := len(str)
for i := 0; i < length; i++ {
s := string(str[i])
index := strings.Index(num2char, s)
v += float64(index) * math.Pow(float64(n), float64(length-1-i)) // 倒序
}
return int(v)
}
測(cè)試
func TestBHex2Num(t *testing.T) {
assert.Equal(t, BHex2Num("1E6K", 36), 65036)
assert.Equal(t, BHex2Num("FE0C", 16), 65036)
assert.Equal(t, NumToBHex(65036, 36), "1E6K")
assert.Equal(t, NumToBHex(65036, 16), "FE0C")
}
應(yīng)用: 生成序號(hào)
日期+[A-Z][0-Z]順序生產(chǎn)吭狡,例如 20190520-A0 20190520-A1 ... 20190520-ZZ
// 按 yymmdd-[A-z][0-Z] 形式生成序號(hào)
func UssNoGenerate(last string) string {
prefix := time.Now().Format(DateTimeDate)
value := 0
if last != "" {
suffix := strings.Split(last, "-")[1]
value = BHex2Num(suffix, 36) + 1
} else {
value = BHex2Num("A0", 36)
}
return prefix + "-" + NumToBHex(value, 36)
}
應(yīng)用測(cè)試:
func TestUssNoGenerate(t *testing.T) {
last := UssNoGenerate("")
for i := 0; i < 40; i++ {
fmt.Println(last)
last = UssNoGenerate(last)
}
}
// 輸出
20190520-A0
20190520-A1
20190520-A2
20190520-A3
...
20190520-AZ
20190520-B0
20190520-B1
20190520-B2
20190520-B3
最開(kāi)始的需求即是生成這些編號(hào),使用字符串截取運(yùn)算等方式丈莺,可以完成划煮,但代碼不忍直視,所以改進(jìn)為些版本缔俄。至少原理上非常容易理解弛秋。
你看出bug來(lái)了嗎,歡迎留言 ... 自己給自己留了坑俐载,bug 自己也看不出來(lái)了