전역 유일한 랜덤 초대 코드 실현 방식

8304 단어
배경.
  • 일상적인 사이트 개발에서 사이트의 판촉 활동을 만나면 초청 선물과 관련된 기능이 있다
  • 친구 초대에 성공하면 해당 보상을 획득, 이때 요청 코드가 요구됩니다
  • 초대 번호는 사용자당 고유해야 함
  •    .       uid     
  •    .            id  ,      ,  code,  uid
  • 방법2, 이런 방식은 uid와 코드 관계를 추가로 기록해야 한다
  • 방법 1, uid에 따라 생성하고 코드에 따라 uid를 반출할 수 있으며 추가 조회를 하지 않아도 비교적 편리하다
  • 이루어지다
  • 기록 방법 1의 실현
  • 긴 숫자에서 특정 길이의 코드로 전환하려면 먼저 코드의 문자 범위를 확정해야 한다
  • 0-9A-Z 36진수로 변환하거나 소문자를 추가할 수 있음
  • 32진수로 변환
  • 01과 o가 혼동하기 쉬운 문자와 보정 문자 F를 제거하고 32자
  • 남음
    코드php 구현 /** * Class ShareCodeUtils * * , * 1) ID * 2) :V * 3) code 6 , 'F':VF * 4) VF 4 , VFAADD * 5) 'F' ,'F' */ class ShareCodeUtils { // 32 (0,1 , o l ,O ,F , ) // , private static $base = ['H', 'V', 'E', '8', 'S', '2', 'D', 'Z', 'X', '9', 'C', '7', 'P','5', 'I', 'K', '3', 'M', 'J', 'U', 'A', 'R', '4', 'W', 'Y', 'L', 'T', 'N', '6', 'B', 'G', 'Q']; // F , private static $pad = "F"; // private static $decimal_len = 32; // code private static $code_min_len = 6; /** * id code * * * @param $id * @return string */ public static function idToCode($id) { $result = ""; while (floor($id / static::$decimal_len) > 0){ $index = $id % static::$decimal_len; $result.= static::$base[$index]; $id = floor($id / static::$decimal_len); } $index = $id % static::$decimal_len; $result.= static::$base[$index]; // code , $code_len = strlen($result); if ($code_len < static::$code_min_len) { $result .= static::$pad; for ($i = 0; $i < static::$code_min_len - $code_len - 1; $i ++) { $result .= static::$base[rand(0, static::$decimal_len -1)]; } } return $result; } /** * code id * code * * eg: N8FASR, F , * N ---> 27 * 8 ---> 3 * 27*32(0) + 3*32(1) = 123 * 32(0) ---> 32 0 * 32(1) ---> 32 1 * * @param $code * @return string */ public static function codeToId($code) { $result = 0; $base_flip_map = array_flip(static::$base); $is_pad = strpos($code, static::$pad); if (!empty($is_pad)) { $len_real = $is_pad; } else { $len_real = strlen($code); } for ($i = 0; $i < $len_real; $i ++) { $str = $code[$i]; $index = $base_flip_map[$str] ?? ''; if ($index === '') { break; } $result += pow(static::$decimal_len, $i) * $index; } return $result; } } $num = "123"; var_dump(ShareCodeUtils::idToCode($num)); $code = "N8FMJ3"; var_dump(ShareCodeUtils::codeToId($code)); go 실현 package main import ( "errors" "fmt" "math/rand" "strings" "time" ) type code struct { base string // , string decimal uint64 // pad string // , code , + , len int // code } // id code func (c *code) idToCode (id uint64) string { mod := uint64(0) res := "" for id!=0 { mod = id % c.decimal id = id / c.decimal res += string(c.base[mod]) } resLen := len(res) if resLen < c.len { res += c.pad for i:=0; i< c.len - resLen - 1; i++ { rand.Seed(time.Now().UnixNano()) res += string(c.base[rand.Intn(int(c.decimal))]) } } return res } // code id func (c *code) codeToId (code string) uint64 { res:=uint64(0) lenCode:=len(code) //var baseArr [] byte = []byte(c.base) baseArr := [] byte (c.base) // byte baseRev := make(map[byte] int) // map for k, v := range baseArr { baseRev[v] = k } // isPad := strings.Index(code, c.pad) if isPad != -1 { lenCode = isPad } r := 0 for i:=0; i< lenCode; i++ { // if string(code[i]) == c.pad { continue } index := baseRev[code[i]] b := uint64(1) for j:=0; j < r; j ++ { b *= c.decimal } // pow float64 , , pow //res += float64(index) * math.Pow(float64(32), float64(2)) res += uint64(index) * b r ++ } return res } // func (c *code) initCheck () (bool, error) { lenBase := len(c.base) // if c.base == "" { return false, errors.New("base string is nil or empty") } // if uint64(lenBase) != c.decimal { return false, errors.New("base length and len not match") } return true, errors.New("") } func main() { inviteCode := code{ base: "HVE8S2DZX9C7P5IK3MJUAR4WYLTN6BGQ", decimal: 32, pad: "F", len: 6, } // if res, err := inviteCode.initCheck(); !res { fmt.Println(err) return } id := uint64(5509767398598656) code := inviteCode.idToCode(id) fmt.Printf("id=%v, code=%v
    ", id, code) code = "HHC59YC8U6S" id = inviteCode.codeToId(code) fmt.Printf("code=%v, id=%v
    ", code, id) }
    go 실현2 package main import( "container/list" "errors" "fmt" ) var baseStr string = "HVE8S2DZX9C7P5IK3MJUAR4WYLTN6BGQ" var base [] byte = []byte(baseStr) var baseMap map[byte] int func InitBaseMap(){ baseMap = make(map[byte]int) for i, v := range base { baseMap[v] = i } } func Base34(n uint64)([]byte){ quotient := n mod := uint64(0) l := list.New() for quotient != 0 { //fmt.Println("---quotient:", quotient) mod = quotient%32 quotient = quotient/32 l.PushFront(base[int(mod)]) //res = append(res, base[int(mod)]) //fmt.Printf("---mod:%d, base:%s
    ", mod, string(base[int(mod)])) } listLen := l.Len() if listLen >= 6 { res := make([]byte,0,listLen) for i := l.Front(); i != nil ; i = i.Next(){ res = append(res, i.Value.(byte)) } return res } else { res := make([]byte,0,6) for i := 0; i < 6; i++ { if i < 6-listLen { res = append(res, base[0]) } else { res = append(res, l.Front().Value.(byte)) l.Remove(l.Front()) } } return res } } func Base34ToNum(str []byte)(uint64, error){ if baseMap == nil { return 0, errors.New("no init base map") } if str == nil || len(str) == 0 { return 0, errors.New("parameter is nil or empty") } var res uint64 = 0 var r uint64 = 0 for i:=len(str)-1; i>=0; i-- { v, ok := baseMap[str[i]] if !ok { fmt.Printf("") return 0, errors.New("character is not base") } var b uint64 = 1 for j:=uint64(0); j%s, %d
    ", string(res), len(res)) str := "VIVZ4EH" num, err := Base34ToNum([]byte(str)) if err == nil { fmt.Printf("===============base:%s->%d
    ", str, num) } else { fmt.Printf("===============err:%s
    ", err.Error()) } }
    총결산
  • 이번 실현은 php와 고 두 언어로 이루어진다
  • 가장 큰 소감은 고의 유형 전환이 비교적 번거롭다는 것이다. 모두 강한 유형이기 때문이다
  • 와 php는 아직 다르다
  • 하지만 고의 문법 코드를 더 익힌 셈이다
  • 전재 대상:https://www.cnblogs.com/fanfan259/p/11423288.html

    좋은 웹페이지 즐겨찾기