【问题标题】:How to fast convert (recode) int64 to character-limited String? [closed]如何将 int64 快速转换(重新编码)为字符限制字符串? [关闭]
【发布时间】:2016-01-30 13:11:41
【问题描述】:

我正在寻找一种方法,将仅由数字 [0,1,2,...8,9] 组成的字符串重新编码为另一个不同字符集的字符串,例如数字和字母 [0,1,。 ..9,a,b,...z](例如)。结果字符串通常应该比纯数字字符串短。该方法应该是可逆的并且应该是快速的。 C# 答案中的源代码将不胜感激,但也欢迎一般的想法;-) 示例:

Input:  "1234567890123"
Output: "ar4cju7d"

应用于“ar4cju7d”的反转方法的输出应该是“1234567890123”。

【问题讨论】:

  • 您显示的示例输入溢出了Int64,其最大值为9223372036854775807。因此,您最好更改问题的标题或使您的要求更具体一些。也不要犹豫,展示你迄今为止为实现目标所做的努力,解释你在代码中遇到的特殊困难。因为在当前状态下,您的问题更适合 rent-a-coder 之类的网站,而不是 StackOverflow。
  • “有点加密”非常违背无需密钥即可反转的编码概念。也许使用 base64 或 base32?
  • “密码学”部分没有得到很好的解释。我删除了它。我想说的是,原始数字不应该轻易地从输出字符串中导出,但这可以通过在编码之前向输入字符串添加一个秘密数字来轻松实现。这是一种非常轻量级的密码学,但在这种情况下就足够了。
  • @DarinDimitrov 我的错。我纠正了错误。

标签: c# string character-encoding recode


【解决方案1】:

如果您的输入始终是 Int64,那么您可以检查Base36 编码。这是sample implementation:

// Edit: Slightly updated on 2011-03-29

/// <summary>
/// A Base36 De- and Encoder
/// </summary>
public static class Base36
{
    private const string CharList = "0123456789abcdefghijklmnopqrstuvwxyz";

    /// <summary>
    /// Encode the given number into a Base36 string
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    public static String Encode(long input)
    {
        if (input < 0) throw new ArgumentOutOfRangeException("input", input, "input cannot be negative");

        char[] clistarr = CharList.ToCharArray();
        var result = new Stack<char>();

        while (input != 0)
        {
            result.Push(clistarr[input % 36]);
            input /= 36;
        }

        return new string(result.ToArray());
    }

    /// <summary>
    /// Decode the Base36 Encoded string into a number
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    public static Int64 Decode(string input)
    {
        var reversed = input.ToLower().Reverse();
        long result = 0;
        int pos = 0;

        foreach (char c in reversed)
        {
            result += CharList.IndexOf(c) * (long)Math.Pow(36, pos);
            pos++;
        }

        return result;
    }
}

可以应用于您的示例:

long input = 1234567890123;
string encoded = Base36.Encode(input); // yields "fr5hugnf"
long originalInput = Base36.Decode(encoded); // yields 1234567890123

【讨论】:

  • 很好的编码,如果输入确实总是int64,这将很合适。如果 OP 想要更多的混淆,你可以做一个字符替换(即用每个 'f' 替换一个 'L' 等,简单的替换密码),这也是可逆的并且阻碍人们尝试常见的编码(如 base64,但 base36 是已经很罕见了)。因此,很好的答案。
  • 我当然同意 ;-)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-06-19
  • 2019-07-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-03-02
  • 1970-01-01
相关资源
最近更新 更多