周梦康 发表于 2015-12-14 4628 次浏览 标签 : 算法

公司需要一些简单的邀请码业务,所以写了如下代码

/**
 * Created by zhoumengkang on 14/12/15.
 */
public class InviteCodeUtil {

    private static final int offset = 24;
    private static final String stopChar = "Z";
    private static final int minCodeLen = 4;

    private static final Map<Integer,String> codeMap = new HashMap<Integer, String>(){{
        put(0,"A");
        put(1,"B");
        put(2,"C");
        put(3,"D");
        put(4,"E");
        put(5,"F");
        put(6,"G");
        put(7,"H");
        put(8,"I");
        put(9,"J");
        put(10,"K");
        put(11,"L");
        put(12,"M");
        put(13,"N");
        put(14,"P");
        put(15,"Q");
        put(16,"R");
        put(17,"S");
        put(18,"T");
        put(19,"U");
        put(20,"V");
        put(21,"W");
        put(22,"X");
        put(23,"Y");
    }};

    private static final Map<String,Integer> intMap = new HashMap<String,Integer>(){{
        put("A",0);
        put("B",1);
        put("C",2);
        put("D",3);
        put("E",4);
        put("F",5);
        put("G",6);
        put("H",7);
        put("I",8);
        put("J",9);
        put("K",10);
        put("L",11);
        put("M",12);
        put("N",13);
        put("P",14);
        put("Q",15);
        put("R",16);
        put("S",17);
        put("T",18);
        put("U",19);
        put("V",20);
        put("W",21);
        put("X",22);
        put("Y",23);
    }};

    /**
     * 根据 id 生成邀请码 6 位
     * 如果是 6 位的邀请码只能支持 191102976 1亿9千万用户
     * 我们自己的产品我想应该是够用了
     *
     * @param id
     * @return
     */
    public static String createCode(int id){
        String code = int2chars(id);
        if (code.length() < (minCodeLen - 1)){
            code = code + stopChar + codeTail(code);
        } else if (code.length() < minCodeLen){
            code = code + stopChar;
        }
        return code;
    }

    /**
     * 从邀请获取用户 id
     *
     * @param code
     * @return
     */
    public static int codeRecover(String code){
        int len = code.indexOf(stopChar);
        if (len > 0) {
            code = code.substring(0,len);
        }
        return chars2int(code);
    }

    private static String codeTail(String code){
        String res = "";
        String lastChar = code.substring(code.length()-1,code.length());// 原code的尾数
        for (int i = 0; i < (minCodeLen - 1 - code.length()); i++) {
            res += lastChar;
        }
        return res;
    }


    private static String int2chars(int id){
        int div = id/offset;
        int remainder = id%offset;

        if (div == 0){
            return codeMap.get(id);
        } else if (div < offset) {
            return codeMap.get(div) + codeMap.get(remainder);
        } else {
            return int2chars(div) + codeMap.get(remainder);
        }
    }

    private static int chars2int(String chats){
        int res = 0;
        int codeLen = chats.length();
        for (int i = 0; i < codeLen; i++) {
            String a = chats.substring(i,i+1);
            if (intMap.containsKey(a)){
                res += intMap.get(a)*(Math.pow(offset,(codeLen-i-1)));
            }else{
                res = 0;
                break;
            }
        }
        return res;
    }
}

PHP 版本

<?php
/**
 * 自定义 60 进制转换
 * User: 梦康 https://mengkang.net
 * Date: 17/12/13
 * Time: 下午4:28
 */

namespace Library;


class InviteCodeUtil
{
    private static $offset = 60;
    private static $stopChar = "Y";
    private static $minCodeLen = 9;

    public static function codeMap()
    {
        static $map = [];
        if (!empty($map)) {
            return $map;
        }

        $start = 0;

        for ($i = 0; $i < 10; $i++) {
            $map[$start] = $i;
            $start++;
        }

        for ($i = ord("a"), $s = ord("z"); $i <= $s; $i++) {
            $map[$start] = chr($i);
            $start++;
        }

        for ($i = ord("A"), $s = ord("Y"); $i < $s; $i++) {
            $map[$start] = chr($i);
            $start++;
        }

        return $map;
    }

    /**
     * @param      $uid
     * @param bool $autoComplete
     *
     * @return mixed|string
     */
    public static function createCode($uid, $autoComplete = false)
    {
        $code = self::int2chars($uid);

        if ($autoComplete && strlen($code) < self::$minCodeLen) {
            $code = $code . self::$stopChar . self::codeTail($code);
        }

        return $code;
    }

    public static function codeRecover($code)
    {
        $len = strpos($code, self::$stopChar);
        if ($len > 0) {
            $code = substr($code, 0, $len);
        }

        return self::chars2int($code);
    }

    private static function codeTail($code)
    {
        $res = "";
        $map = self::codeMap();
        $mapSize = count($map);

        $count = self::$minCodeLen - strlen($code);
        for ($i = 0; $i < $count; $i++) {
            $res .= $map[mt_rand(0, $mapSize - 1)];
        }

        return $res;
    }

    /**
     * 数字转字符串
     *
     * @param $int
     *
     * @return mixed|string
     */
    public static function int2chars($int)
    {

        if ($int > PHP_INT_MAX) {
            return $int;
        }

        $map = self::codeMap();

        $res = (int)floor($int / self::$offset);
        $remainder = $int % self::$offset;

        if ($res === 0) {
            return $map[$int];
        } elseif ($res < self::$offset) {
            return $map[$res] . $map[$remainder];
        } else {
            return self::int2chars($res) . $map[$remainder];
        }
    }

    /**
     * 字符串转数字
     *
     * @param $string
     *
     * @return float|int
     */
    public static function chars2int($string)
    {
        $map = self::codeMap();
        $map = array_flip($map);

        $res = 0;

        $len = strlen($string);

        for ($i = 0; $i < $len; $i++) {
            $s = substr($string, $i, 1);
            if (isset($map[$s])) {
                $res += $map[$s] * (pow(self::$offset, ($len - $i - 1)));
            } else {
                $res = 0;
                break;
            }
        }

        return $res;
    }
    
}


👇 下面是我的公众号,高质量的博文我会第一时间同步到公众号,给个关注吧!

评论列表