Browse Source

支持中文数字转换

xiaochang 4 years ago
parent
commit
5041cab107
6 changed files with 64 additions and 24 deletions
  1. 8 2
      conf/conf.go
  2. 1 0
      config.conf
  3. 1 1
      lib/shorturl/shorturl.go
  4. 41 16
      lib/tools.go
  5. 5 1
      web/api/loadUrl.go
  6. 8 4
      web/api/shortUrl.go

+ 8 - 2
conf/conf.go

@@ -2,11 +2,11 @@ package conf
 
 import (
 	"bytes"
+	"github.com/BurntSushi/toml"
 	"io/ioutil"
 	"log"
 	"os"
 	"runtime"
-	"github.com/BurntSushi/toml"
 )
 
 type sequenceDB struct {
@@ -31,6 +31,8 @@ type common struct {
 	BlackShortURLsMap map[string]bool
 	BaseString        string `toml:"base_string"`
 	BaseStringLength  uint64
+	BaseStringCn        string `toml:"base_string_cn"`
+	BaseStringCnLength  uint64
 	DomainName        string `toml:"domain_name"`
 	Schema            string `toml:"schema"`
 }
@@ -75,7 +77,11 @@ func MustParseConfig(configFile string) {
 	}
 
 	// base string
-	Conf.Common.BaseStringLength = uint64(len(Conf.Common.BaseString))
+	// Conf.Common.BaseStringLength = uint64(len(Conf.Common.BaseString))
+	baseStringRune := []rune(Conf.Common.BaseString)
+	Conf.Common.BaseStringLength = uint64(len(baseStringRune))
+	baseStringCnRune := []rune(Conf.Common.BaseStringCn)
+	Conf.Common.BaseStringCnLength = uint64(len(baseStringCnRune))
 }
 func init() {
 	runtime.GOMAXPROCS(runtime.NumCPU())

+ 1 - 0
config.conf

@@ -31,6 +31,7 @@ black_short_urls = ["version","health","short","expand","css","js","fuck","stupi
 
 # Base string used to generate short url
 base_string = "FnvUcfRyxsKuEMraDOPSe9Y8BZh0Tmk1bV65ld42XgGzNC7wp3JWLqAtiQjHoI"
+base_string_cn = "牛虎充宗绿红亿竹宁总兔蓉兽克合雪琬伦珍猴妃灵阴虫巽晗余月东天黑和空工绯夏沫欣紫悦艮白西羽坤涵梦爽玉翔旭栋鹏衷晴北水衣终琴青丙攻鼠兰日楚童鸟鱼景忆甲冰丰狗猪茹枫虹坎辰秋飞鸿忠依冬舒蛇归公种丛山茜菊车相洪春好梅乙居美维地琳河冲冻气象中乾蓝湖橙启海震江容莹思马茗阳离僧桐羊兑同倩汉丁非灰书瑶南钟希功彤筒乐于渔封晨初松农人予鸡色赤龙寺花泽夕丽风飘"
 # base_string = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
 
 # Short url service domain name. This is used to filter short url loop.

+ 1 - 1
lib/shorturl/shorturl.go

@@ -121,7 +121,7 @@ func (shorter *shorter) Short(longURL string) (shortURL string, err error) {
 			return "", errors.New("get next sequence error")
 		}
 
-		shortURL = lib.Int2String(seq)
+		shortURL = lib.Int2String(seq,false)
 		if _, exists := conf.Conf.Common.BlackShortURLsMap[shortURL]; exists {
 			continue
 		} else {

+ 41 - 16
lib/tools.go

@@ -1,45 +1,70 @@
 package lib
 
 import (
+	"git.sfnt.net/sfnt/cnlink/conf"
 	"math"
 	"strings"
-
-	"git.sfnt.net/sfnt/cnlink/conf"
 )
 
 // Int2String converts an unsigned 64bit integer to a string.
-func Int2String(seq uint64) (shortURL string) {
+func Int2String(seq uint64, cn bool) (shortURL string) {
 	charSeq := []rune{}
+	baseStringRune := []rune(conf.Conf.Common.BaseString)
+	baseStringLength :=conf.Conf.Common.BaseStringLength
+	if cn == true {
+		baseStringRune = []rune(conf.Conf.Common.BaseStringCn)
+		baseStringLength =conf.Conf.Common.BaseStringCnLength
+	}
 	if seq != 0 {
 		for seq != 0 {
-			mod := seq % conf.Conf.Common.BaseStringLength
-			div := seq / conf.Conf.Common.BaseStringLength
-			charSeq = append(charSeq, rune(conf.Conf.Common.BaseString[mod]))
+			mod := seq % baseStringLength
+			div := seq / baseStringLength
+			charSeq = append(charSeq, rune(baseStringRune[mod]))
 			seq = div
 		}
 	} else {
-		charSeq = append(charSeq, rune(conf.Conf.Common.BaseString[seq]))
+		charSeq = append(charSeq, rune(baseStringRune[seq]))
 	}
 
 	tmpShortURL := string(charSeq)
-	shortURL = reverse(tmpShortURL)
+	shortURL = string(reverse(tmpShortURL))
 	return
 }
 
 // String2Int converts a short URL string to an unsigned 64bit integer.
-func String2Int(shortURL string) (seq uint64) {
-	shortURL = reverse(shortURL)
-	for index, char := range shortURL {
-		base := uint64(math.Pow(float64(conf.Conf.Common.BaseStringLength), float64(index)))
-		seq += uint64(strings.Index(conf.Conf.Common.BaseString, string(char))) * base
+func String2Int(shortURL string, cn bool) (seq uint64) {
+	shortURLRune := reverse(shortURL)
+	baseString :=conf.Conf.Common.BaseString
+	baseStringRune := []rune(baseString)
+	baseStringLength :=conf.Conf.Common.BaseStringLength
+	if cn == true {
+		baseString =conf.Conf.Common.BaseStringCn
+		baseStringRune = []rune(baseString)
+		baseStringLength =conf.Conf.Common.BaseStringCnLength
+	}
+	for index, char := range shortURLRune {
+		base := uint64(math.Pow(float64(baseStringLength), float64(index)))
+		if cn==true {
+			seq += uint64(getRuneIndex(baseStringRune, string(char))) * base
+		} else {
+			seq += uint64(strings.Index(baseString, string(char))) * base
+		}
 	}
 	return
 }
-
-func reverse(s string) string {
+func getRuneIndex(r []rune, c string) (i int){
+	for index ,rc := range r {
+		if rc == ([]rune(c))[0] {
+			i = index
+			return i
+		}
+	}
+	return -1
+}
+func reverse(s string) []rune {
 	r := []rune(s)
 	for i, j := 0, len(r)-1; i < len(r)/2; i, j = i+1, j-1 {
 		r[i], r[j] = r[j], r[i]
 	}
-	return string(r)
+	return r
 }

+ 5 - 1
web/api/loadUrl.go

@@ -5,10 +5,14 @@ import (
 	"github.com/gin-gonic/gin"
 	"log"
 	"net/http"
+	"time"
 )
 func LoadUrl(c *gin.Context){
 	url,_ := c.GetQuery("url")
-	res, err := http.Get(url)
+	client :=http.Client{
+		Timeout: 2*time.Second,
+	}
+	res, err := client.Get(url)
 
 	if err != nil {
 		log.Print(err)

+ 8 - 4
web/api/shortUrl.go

@@ -11,15 +11,19 @@ func Redirect(c *gin.Context){
 	sq, err := shorturl.Shorter.GetSequence()
 	if err != nil {
 		c.JSON(200, gin.H{
-			"message": lib.String2Int(sid),
-			"sequence": lib.Int2String(sq),
+			"message": lib.String2Int(sid,false),
+			"sequence": lib.Int2String(sq,false),
+			"message_cn": lib.String2Int(sid,true),
+			"sequence_cn": lib.Int2String(sq,true),
 			"sequence_id": sq,
 			"error": err,
 		})
 	} else {
 		c.JSON(200, gin.H{
-			"message": lib.String2Int(sid),
-			"sequence": lib.Int2String(sq),
+			"message": lib.String2Int(sid,false),
+			"sequence": lib.Int2String(sq,false),
+			"message_cn": lib.String2Int(sid,true),
+			"sequence_cn": lib.Int2String(sq,true),
 			"sequence_id": sq,
 		})
 	}