关于c#:如何使用大写字母和数字对长号进行编码以使其缩短?

How could I encode a long number using uppercase letters and numbers to make it shorter to type?

是否有一种方法可以将长数字(例如12349874529768521)编码为小写字母和数字以缩短其长度?其想法是用户可能在一张纸上有一个长数字。

在我看来,如果有更多的符号可用,结果的数字可以缩短。所以我在寻找类似十六进制的东西,但是使用更大的符号空间a-z而不是a-f。

这是C(如果重要的话)


base32编码的目的是产生一个明确,紧凑,人可读(和非淫秽!)陈述。维基百科:

Base32 has a number of advantages over Base64:

  • The resulting character set is all one case, which can often be beneficial when using a case-insensitive filesystem, spoken language, or human memory.

  • The
    result can be used as a file name because it can not possibly contain the '/' symbol, which is the Unix path separator.

  • The alphabet can be selected to avoid similar-looking pairs of different symbols, so the strings can be accurately transcribed by hand. (For example, the RFC 4648 symbol set omits the digits for one, eight and zero, since they could be confused with the letters 'I', 'B', and 'O'.)

  • A result excluding padding can be included in a URL without encoding any characters.

Base32 also has advantages over hexadecimal/Base16: Base32
representation takes roughly 20% less space. (1000 bits takes 200
characters, compared to 250 for Base16)

道格拉斯·克罗克福德关于base32编码的原创文章也值得一读。

编辑:这里有一点C它可以对整数进行base-n编码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
class Program {
    private const string BINARY ="01";
    private const string DECIMAL ="0123456789";
    private const string HEX ="0123456789abcdef";
    private const string BASE32 ="0123456789abcdefghjkmnpqrstvwxyz";

    static string EncodeInt32(string alphabet, int value) {
        var sb = new StringBuilder();
        while (value > 0) {
            sb.Insert(0, alphabet[value % alphabet.Length]);
            value = value / alphabet.Length;
        }
        return sb.ToString();
    }

    static int DecodeInt32(string alphabet, string value) {
        int result = 0;
        int b = alphabet.Length;
        int pow = 0;
        for (var i = value.Length-1; i >= 0; i--) {
            result += (int)(Math.Pow(b, pow++)) * alphabet.IndexOf(value[i]);
        }
        return (result);
    }

    static void Main(string[] args) {
        for (var i = 0; i < 1234567890; i += 1234567) {
            Console.WriteLine("{0} {1} {2}", i, EncodeInt32(BASE32, i), DecodeInt32(BASE32, EncodeInt32(BASE32, i)));
        }
        Console.ReadKey(false);
    }
}

显示典型字符串长度缩减的示例输出:

1
2
3
4
5
6
7
1227159598 14j9y1e 1227159598
1228394165 14kfknn 1228394165
1229628732 14mn99w 1229628732
1230863299 14ntyy3 1230863299
1232097866 14q0mja 1232097866
1233332433 14r6a6h 1233332433
1234567000 14sbztr 1234567000


用一个BaseN方法把你的长度编码/解码成一个字符串,字符串中有你自己定义的字符,怎么样?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
public static class BaseN
{
    private const string CharList ="0123456789abcdefghijklmnopqrstuvwxyz";
    public static String Encode(long input)
    {
        if (input < 0) throw new ArgumentOutOfRangeException("input", input,"input cannot be negative");
        var result = new System.Collections.Generic.Stack<char>();
        while (input != 0)
        {
            result.Push(CharList[(int)(input % CharList.Length)]);
            input /= CharList.Length;
        }
        return new string(result.ToArray());
    }

    public static long Decode(string input)
    {
        long result = 0, pos = 0;
        foreach (char c in input.Reverse())
        {
            result += CharList.IndexOf(c) * (long)Math.Pow(CharList.Length, pos);
            pos++;
        }
        return result;
    }
}

用途:

1
2
long number = 12349874529768521;
string result = BaseN.Encode(number);

Sample:

https://dotnetfiddle.net/odwflk


下面是与其他方法类似的方法,使用base-n转换:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
using System;
using System.Text;

namespace ConsoleApp3
{
    class Program
    {
        static void Main()
        {
            long n = 12349874529768521;

            string baseChars ="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz@#";

            var encoded = AsBaseN(n, baseChars.ToCharArray());
            Console.WriteLine(encoded); // Prints"9HXNyK2uh"

            long decoded = AsLong(encoded, baseChars.ToCharArray());
            Console.WriteLine(decoded); // Prints"12349874529768521"
        }

        public static string AsBaseN(long value, char[] baseChars)
        {
            var result = new StringBuilder();
            int targetBase = baseChars.Length;

            do
            {
                result.Append(baseChars[value % targetBase]);
                value /= targetBase;
            }
            while (value > 0);

            return result.ToString();
        }

        public static long AsLong(string number, char[] baseChars)
        {
            long result = 0;
            int numberBase = baseChars.Length;
            long multiplier = 1;

            foreach (char c in number)
            {
                result += multiplier * Array.IndexOf(baseChars, c);
                multiplier *= numberBase;
            }

            return result;
        }
    }
}

如果需要不同的允许字符集,只需根据需要更改baseChars。例如,如果只需要0-9和a-z:

1
string baseChars ="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";

这给出了T3OPA1YNLD3的结果(基36),而不是9HXNyK2uh的结果(基64)。


我想你是说你想用更少的字符来表示数字。以36为底将执行此操作(0-9,a-z)。


您可以使用Base 36编码器。

Base36 is a binary-to-text encoding scheme that represents binary data in an ASCII string format by translating it into a radix-36 representation. The choice of 36 is convenient in that the digits can be represented using the Arabic numerals 0–9 and the Latin letters A–Z1 (the ISO basic Latin alphabet).

这里有一个例子,但任何一个都应该有效:https://github.com/thewindev/csharpbase36

示例用法

1
2
3
4
5
6
7
8
// Encoding
Base36.Encode(10);    // returns"A"
Base36.Encode(10000); // returns"7PS"

// Decoding
Base36.Decode("Z");   // returns 35L
Base36.Decode("10");  // returns 36L
Base36.Decode("7PS"); // returns 10000L

默认情况下,使用大写字母。如果你真的想要小写,那么一个简单的string.ToLowerInvarient()就可以改变它。

但是,大写通常更容易阅读,这就是默认情况下使用它的原因,因此您可能需要考虑使用大写而不是小写。


您可以查看base64编码。它使用09AZAZ+/字符。或者base36,如果你只对0--9--A--Z感兴趣。