基于用户id生成邀请码

参考文章:https://blog.csdn.net/shamg/article/details/80385782

原文是Java语言的

下面是C# 改写

public  class InviteCodeHelp
    {
        //验证码长度
        private static int LEN = 6;
        //验证码字符列表
        //private static char[] STUFFS = {
        //    'A','B','C','D','E','F',
        //    'G','H','I','J','K','L',
        //    'M','N','P','Q','R','S',
        //    'T','U','V','W','X','Y',
        //    '1','2','3','4','5','6',
        //    '7','8'};
        //验证码字符列表
        //private static char[] STUFFS = {
        //    'A','B','4','N','P','U',
        //    'N','E','I','2','K','L',
        //    'W','G','H','Q','R','5',
        //    'T','7','D','M','8','Y',
        //    '1','J','3','C','S','6',
        //    'F','X'};
        //验证码字符列表【生成的字符可打乱可添加小写,不影响转换】
        private static char[] STUFFS = {
            'A','B','4','N','P','U',
            'N','E','I','2','K','L',
            'W','G','H','Q','R','5',
            'T','7','D','M','8','Y',
            '1','J','3','C','S','6',
            'F','Z','0','X'};
        private static int PERMUTATION = permutation(LEN);
        private static int MAX_COMBINATION = combination(STUFFS.Length, LEN);

        private static int combination(int n, int m)
        {
            int com = 1;
            for (int i = n - m + 1; i <= n; ++i)
            {
                com *= i;
            }
            for (int i = 2; i <= m; ++i)
            {
                com /= i;
            }
            return com;
        }

        private static int permutation(int n)
        {
            int per = 1;
            for (int i = 2; i <= n; ++i)
            {
                per *= i;
            }
            return per;
        }
        //邀请码转成用户id
        public static int decode(String code)
        {
            if (code.Length != LEN)
            {
                LXFrame.WriteTextLog("decode", "invalid code", DateTime.Now);
            }
            char[] chars = new char[LEN];
            for (int i = 0; i < LEN; ++i)
            {
                chars[i] = code[i];
            }
            int com = combination(chars);
            int per = permutation(chars);
            int codeval = com * PERMUTATION + per;
            codeval -= 258369;//解密偏差量【可更改】
            return codeval;
        }
        //用户id生成邀请码
        public static String encode(int val)
        {
            val += 258369;//加密偏差量【可更改】
            int com = val / PERMUTATION;
            if (com >= MAX_COMBINATION)
            {
                //throw new RuntimeException("id can't be greater than 652458239");
                LXFrame.WriteTextLog("encode", "invalid code", DateTime.Now);
            }
            int per = val % PERMUTATION;
            char[] chars = combination(com);
            chars = permutation(chars, per);
            return new String(chars);
        }

        private static char[] combination(int com)
        {
            char[] chars = new char[LEN];
            int start = 0;
            int index = 0;
            while (index < LEN)
            {
                for (int s = start; s < STUFFS.Length; ++s)
                {
                    int c = combination(STUFFS.Length - s - 1, LEN - index - 1);
                    if (com >= c)
                    {
                        com -= c;
                        continue;
                    }
                    chars[index++] = STUFFS[s];
                    start = s + 1;
                    break;
                }
            }
            return chars;
        }

        public static char[] sort(char[] src)
        {
            char[] sort = new char[src.Length];
            int index = 0;
            for (int i = 0; i < STUFFS.Length; ++i)
            {
                if (find(src, STUFFS[i]) != -1)
                {
                    sort[index++] = STUFFS[i];
                }
            }
            return sort;
        }

        private static int combination(char[] chars)
        {
            int[] offset = new int[LEN];
            char[] sort = InviteCodeHelp.sort(chars);
            for (int i = 0; i < sort.Length; ++i)
            {
                offset[i] = find(STUFFS, sort[i]);
                if (offset[i] == -1)
                {
                    //throw new RuntimeException("invalid code");
                    LXFrame.WriteTextLog("combination", "invalid code", DateTime.Now);
                }
            }
            int com = 0;
            for (int i = 0; i < offset.Length; ++i)
            {
                if (i == 0)
                {
                    if (offset[0] == 0)
                    {
                        continue;
                    }
                    for (int n = 0; n < offset[0]; ++n)
                    {
                        com += combination(STUFFS.Length - n - 1, LEN - 1);
                    }
                    continue;
                }

                if (offset[i] - offset[i - 1] <= 1)
                {
                    continue;
                }

                for (int n = offset[i - 1] + 1; n < offset[i]; ++n)
                {
                    com += combination(STUFFS.Length - n - 1, LEN - i - 1);
                }
            }

            return com;
        }

        private static char[] permutation(char[] chars, int per)
        {
            //char[] tmpchars = new char[chars.Length];
            char[] tmpchars = chars;
            //System.arraycopy(chars, 0, tmpchars, 0, chars.Length);
            int[] offset = new int[chars.Length];
            int step = chars.Length;
            for (int i = chars.Length - 1; i >= 0; --i)
            {
                offset[i] = per % step;
                per /= step;
                step--;
            }

            for (int i = 0; i < chars.Length; ++i)
            {
                if (offset[i] == 0)
                    continue;
                char tmp = tmpchars[i];
                tmpchars[i] = tmpchars[i - offset[i]];
                tmpchars[i - offset[i]] = tmp;
            }

            return tmpchars;
        }

        private static int find(char[] chars, char ch)
        {
            for (int i = 0; i < chars.Length; ++i)
            {
                if (chars[i] == ch)
                {
                    return i;
                }
            }
            return -1;
        }

        private static int permutation(char[] chars)
        {
            char[] sort = InviteCodeHelp.sort(chars);
            int[] offset = new int[chars.Length];
            for (int i = chars.Length - 1; i >= 0; --i)
            {
                int f = find(chars, sort[i]);
                offset[i] = i - f;
                char tmp = chars[i];
                chars[i] = chars[i - offset[i]];
                chars[i - offset[i]] = tmp;
            }
            int per = 0;
            int step = 1;
            for (int i = 0; i < offset.Length; ++i)
            {
                per = per * step + offset[i];
                step++;
            }
            return per;
        }
    }

 

posted @ 2022-02-14 14:06    阅读(403)  评论(0编辑  收藏  举报