<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      使用Go語(yǔ)言開(kāi)發(fā)一個(gè)短鏈接服務(wù):四、生成code算法

      章節(jié)

      ?使用Go語(yǔ)言開(kāi)發(fā)一個(gè)短鏈接服務(wù):一、基本原理  

      ?使用Go語(yǔ)言開(kāi)發(fā)一個(gè)短鏈接服務(wù):二、架構(gòu)設(shè)計(jì)

      ?使用Go語(yǔ)言開(kāi)發(fā)一個(gè)短鏈接服務(wù):三、項(xiàng)目目錄結(jié)構(gòu)設(shè)計(jì)

      ?使用Go語(yǔ)言開(kāi)發(fā)一個(gè)短鏈接服務(wù):四、生成code算法

      ?使用Go語(yǔ)言開(kāi)發(fā)一個(gè)短鏈接服務(wù):五、添加和獲取短鏈接

      ?使用Go語(yǔ)言開(kāi)發(fā)一個(gè)短鏈接服務(wù):六、鏈接跳轉(zhuǎn)

      ??Gitee https://gitee.com/alxps/short_link

        Github https://github.com/1911860538/short_link

       

        上一篇介紹了項(xiàng)目目錄接口,這篇將實(shí)現(xiàn)短鏈接code算法。

       

      前言

      ??假如某個(gè)用戶(hù),有個(gè)長(zhǎng)鏈接為:https://github.com/gin-gonic/gin/blob/master/internal/bytesconv/bytesconv_1.19.go,我們短鏈接服務(wù)域名為https://a.b.c,為這個(gè)長(zhǎng)鏈接生成對(duì)應(yīng)的短鏈接為https://a.b.c/N26jas。這里code便是Na6jas。

      ??code必須滿(mǎn)足以下幾個(gè)要求:

      ????1、只包含,大小寫(xiě)字母或數(shù)字

      ????2、短

      ????3、唯一

      ??大小字母加上數(shù)字,共62個(gè),當(dāng)code長(zhǎng)度為N時(shí),code可以有62的N次方個(gè)。N為5、6、7,code個(gè)數(shù)大約為1600萬(wàn), 568億, 3.5萬(wàn)億。586億夠用,因此系統(tǒng)code長(zhǎng)度為6,夠短。

       

      如何生成唯一code

      ??這還不簡(jiǎn)單!生成6位隨機(jī)大小寫(xiě)字母或數(shù)字的字符,數(shù)據(jù)庫(kù)存在,重新隨機(jī)生成,遞歸直到不沖突。本篇完……,當(dāng)然不是。

      ??至于如何生成6位隨機(jī)大小寫(xiě)字母或數(shù)字,可以看看這篇文章:Golang 生成隨機(jī)字符串的八種方式與性能測(cè)試。文章隨機(jī)字符串只有大小寫(xiě)字母,我們?cè)诖嘶A(chǔ)上稍作修改,代碼如下:

      package service
      
      import (
      	"math/rand"
      	"time"
      	"unsafe"
      )
      
      const letters = "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
      
      var src = rand.NewSource(time.Now().UnixNano())
      
      const (
      	// 6 bits to represent a character index
      	charIdBits = 6
      	// All 1-bits as many as charIdBits
      	charIdMask = 1<<charIdBits - 1
      	// 由于現(xiàn)在包含了62個(gè)字符,計(jì)算新的charIdMax
      	charIdMax = 63 / charIdBits
      	// 字符集的大小
      	charsetSize = len(letters)
      )
      
      func randStr(n int) string {
      	b := make([]byte, n)
      	for i, cache, remain := n-1, src.Int63(), charIdMax; i >= 0; {
      		if remain == 0 {
      			cache, remain = src.Int63(), charIdMax
      		}
      		if idx := int(cache & charIdMask); idx < charsetSize {
      			b[i] = letters[idx]
      			i--
      		}
      		cache >>= charIdBits
      		remain--
      	}
      	return unsafe.String(unsafe.SliceData(b), len(b))
      }

       ??但是,我想法是,code要根據(jù)用戶(hù)id和長(zhǎng)鏈接url推算出來(lái),即相同的user_id+long_url,每次得到的code都一樣。先上代碼,再講思路

      package service
      
      import (
      	"crypto/md5"
      	"encoding/hex"
      	"hash/fnv"
      	"io"
      	"unsafe"
      
      	"github.com/1911860538/short_link/config"
      )
      
      const letters = "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
      
      var confCodeLen = config.Conf.Core.CodeLen
      
      // GenCode
      func GenCode(userId string, longUlr string, salt string) (string, error) {
      	// 首先對(duì)userId+longUrl+salt md5 主要為了防止longUrl包含漢字等字符串
      	hasher := md5.New()
      	if _, err := io.WriteString(hasher, userId+longUlr+salt); err != nil {
      		return "", err
      	}
      	hashStr := hex.EncodeToString(hasher.Sum(nil))
      
      	stepLen := len(hashStr) / confCodeLen
      	remain := len(hashStr) % confCodeLen
      	if remain > 0 {
      		stepLen += 1
      	}
      	lettersLen := uint32(len(letters))
      	b := make([]byte, confCodeLen)
      
      	for i := 0; i < confCodeLen; i++ {
      		// 根據(jù)要生成的code長(zhǎng)度,切分md5字符串
      		var piece string
      		if remain > 0 && i == confCodeLen-1 {
      			piece = hashStr[i*stepLen : i*stepLen+remain]
      		} else {
      			piece = hashStr[i*stepLen : i*stepLen+stepLen]
      		}
      
      		// 為切片元素生成對(duì)應(yīng)的整形數(shù)值
      		h := fnv.New32a()
      		pieceBytes := unsafe.Slice(unsafe.StringData(piece), len(piece))
      		if _, err := h.Write(pieceBytes); err != nil {
      			return "", err
      		}
      		pieceHash32 := h.Sum32()
      
      		// 切片字符的整形,取len(letters)余數(shù),并取letters索引為該余數(shù)的letter
      		letterIdx := pieceHash32 % lettersLen
      		b[i] = letters[letterIdx]
      	}
      
      	return unsafe.String(unsafe.SliceData(b), len(b)), nil
      }

      ??比如user_id為"1f70a466-1449-4676-b2d7-2037341c718e",long_url為"https://i.cnblogs.com/posts/edit;postId=18090256":

      ????1、將user_id+long_url字符串,生成md5的哈希字符串,這一步是為了得到固定長(zhǎng)度的字符。結(jié)果為,"101360eb993b977d9f6969813ee84338"

      ????2、根據(jù)要生成的code長(zhǎng)度,切分步驟1的字符串。我們要得到6位code,因而我們將得到的字符切片結(jié)果為,["101360", "eb993b", "977d9f", "696981", "3ee843", "38"]

      ????3、接著我們對(duì)步驟2每個(gè)字符切片元素,使用fnv哈希,獲得uint32,結(jié)果為[791694210, 3988549581, 2254501405, 2706880430, 3291227237, 2414894606]

      ????4、對(duì)步驟3,uint32切片,每個(gè)元素,取letters長(zhǎng)度余數(shù),獲得余數(shù)切片,[28, 53, 55, 48, 17, 0]

      ????5、取letters索引為步驟4余數(shù)切片的字母或數(shù)字字符,得到最終結(jié)果,"2RTMra"

      ??步驟3/4參考了一致性哈希。當(dāng)然,上面兩種獲取6位code方式憑個(gè)人想法哈,網(wǎng)上也有其它算法實(shí)現(xiàn)可參考。本項(xiàng)目中使用上面說(shuō)的后者。

       

      總結(jié)

      ??本篇講了短鏈接code生成邏輯,下一篇講添加和獲取短鏈接邏輯。

      posted @ 2024-03-26 12:05  ALXPS  閱讀(431)  評(píng)論(0)    收藏  舉報(bào)
      主站蜘蛛池模板: 黑巨人与欧美精品一区| 欧美精品国产综合久久| 亚洲乱码中文字幕久久孕妇黑人| 国产免费网站看v片元遮挡| 日本一区二区三本视频在线观看| 国产成人综合色就色综合| а∨天堂一区中文字幕| 日韩加勒比一本无码精品| 欧美牲交a欧美牲交aⅴ图片| 啦啦啦视频在线日韩精品| 国产在线线精品宅男网址| 欧美一本大道香蕉综合视频| 99视频在线精品国自产拍| 四虎亚洲精品高清在线观看| 99精品久久久久久久婷婷| 国产激情一区二区三区不卡| 精品一区二区免费不卡| 国产精久久一区二区三区| 精品人妻码一区二区三区| 国内偷自第一区二区三区| 久久综合给合久久狠狠97色| 孝义市| 亚洲免费视频一区二区三区| 美女一区二区三区在线观看视频 | 国内精品久久人妻无码妲| 成人午夜无人区一区二区| 在线看免费无码的av天堂| 成人啪精品视频网站午夜| 国产69久久精品成人看| 国产精品店无码一区二区三区| 亚洲人妻精品一区二区| 色偷偷成人综合亚洲精品| 久久99国产精品尤物| 131mm少妇做爰视频| 午夜一区欧美二区高清三区| 久青草国产在视频在线观看| 欧美性猛交xxxx乱大交极品| 国产一区二区三区我不卡| 中文国产成人精品久久不卡| 亚洲18禁私人影院| 亚洲高清国产拍精品熟女|