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



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

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

这将是在 C# 中(如果它很重要)

Base32 编码旨在产生明确、紧凑、人类可读(且非淫秽!)的表示形式。来自维基百科:

与Base64相比,Base32具有许多优点:

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

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

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

  • 排除填充的结果可以包含在 URL 中,而无需对任何字符进行编码。

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

Douglas Crockford关于Base32编码的原始文章也非常值得一读。

编辑:这里有一些C#可以对整数进行base-N编码:

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

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

1227159598 14j9y1e 1227159598
1228394165 14kfknn 1228394165
1229628732 14mn99w 1229628732
1230863299 14ntyy3 1230863299
1232097866 14q0mja 1232097866
1233332433 14r6a6h 1233332433
1234567000 14sbztr 1234567000

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

用法:

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

样本:

https://dotnetfiddle.net/odwFlk

下面是使用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)的结果。

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

您可以使用 base 36 编码器。

Base36 是一种二进制到文本编码方案,通过将二进制数据转换为基数 36 表示形式,以 ASCII 字符串格式表示二进制数据。选择36很方便,因为可以使用阿拉伯数字0-9和拉丁字母A-Z1(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()可以改变这一点。

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

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

相关内容

最新更新