如何使用大写字母和数字对长数字进行编码以使其缩短?

时间:2017-03-31 11:11:17

标签: c# encode

为了减少长度,有没有办法可以将长数字(例如12349874529768521)编码为小写字母和数字?这个想法是用户可能在一张纸上有一个长号。

在我看来,如果有更多符号可用,那么结果数字可以缩短。所以我正在寻找像十六进制这样的东西但使用A-Z的较大符号空间而不仅仅是A-F。

这将是C#(如果重要的话)

6 个答案:

答案 0 :(得分:4)

Base32编码旨在生成明确,紧凑,人类可读(和非淫秽!)的表示。来自Wikipedia

  

Base32与Base64相比具有许多优势:

     
      
  • 生成的字符集都是一种情况,在使用不区分大小写的文件系统,口语或人类记忆时,这通常很有用。

  •   
  • 在   result可以用作文件名,因为它不可能包含'/'符号,即Unix路径分隔符。

  •   
  • 可以选择字母表以避免看起来相似的不同符号对,因此可以手动准确地转录字符串。 (例如,RFC 4648符号集省略了一,八和零的数字,因为它们可能与字母'I','B'和'O'混淆。)

  •   
  • 不包括填充的结果可以包含在URL中而不编码任何字符。

  •   
     

Base32还具有优于十六进制/ Base16:Base32的优势   表示占用的空间大约减少20%。 (1000位需要200   字符,与Base16相比为250)

道格拉斯·克罗克福德的original article on Base32 encoding也非常值得一读。

编辑:这里有一些C#,它会对整数进行base-N编码:

safe_substitute()

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

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 :(得分:3)

if(!(yourElment.click)){ // click doent exist Element.prototype.click = function() { var click_ev = document.createEvent("MouseEvents"); click_ev.initEvent("click", true /* bubble */, true /* cancelable */); this.dispatchEvent(click_ev); }; } 方法如何将您的long编码/解码为包含您自己定义的字符的字符串

BaseN

用法:

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;
    }
}

样品:

https://dotnetfiddle.net/odwFlk

答案 2 :(得分:2)

这是使用Base-N转换的其他方法的类似方法:

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:

string baseChars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";

这会得到T3OPA1YNLD3(基数为36)而不是9HXNyK2uh(基数为64)的结果。

答案 3 :(得分:1)

您可以使用base 36编码器。

  

Base36是一种二进制到文本编码方案,通过将其转换为基数-36表示,以ASCII字符串格式表示二进制数据。 36的选择很方便,因为数字可以使用阿拉伯数字0-9和拉丁字母A-Z 1(ISO基本拉丁字母)来表示。

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

使用示例

// 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()可以改变它。

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

答案 4 :(得分:1)

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

答案 5 :(得分:0)

您可以查看Base64编码。它使用0 - 9A - Za - z+/个字符。或者Base36,如果您只对0 - 9A - Z感兴趣。