编码一个数字,z-base-32的C#实现还是别的什么?

时间:2009-04-08 09:38:41

标签: c# algorithm encoding base32

我需要编码/解码一个长达9位但通常长7位的整数。我想让沟通/记忆更容易 - 它将通过电话,复制和传播进行沟通。粘贴,从卡片/记忆/标签键入,手写在标签上并且通常被滥用!

我希望使用base 32方案减少位数(同时添加校验和)。我最赞成z-base-32(超过RFC4648实现),因为有些设计目标(例如手写)和字母表选择(小写,置换以支持更容易使用的字符)读,写,说,记得)。但是,我找不到C#实现,我担心从现有的Python实现移植。

有没有人有C#实现?或者,是否有人可以使用一组测试用例(规范中的示例除外)来验证端口?

我愿意接受有关替代编码方案的建议。

5 个答案:

答案 0 :(得分:9)

我从Dead帐户提供的代码开始,并根据我的测试进行了一些更改。我希望这很有用。

/// <summary>
/// Author: Ben Maddox
/// </summary>
public class ZBase32Encoder
{
    /*
     * Accepted characters based on code from: 
     * http://www.codeproject.com/KB/recipes/Base32Encoding.aspx?display=Print
     */
    public const string AcceptedCharacters = "ybndrfg8ejkmcpqxot1uwisza345h769";

    public static string Encode(int input)
    {
        string result = "";

        if (input == 0)
        {
            result += AcceptedCharacters[0];
        }
        else
        {
            while (input > 0)
            {
                //Must make sure result is in the correct order
                result = AcceptedCharacters[input%AcceptedCharacters.Length] + result;
                input /= AcceptedCharacters.Length;
            }
        }

        return result;
    }

    public static int Decode(string input)
    {
        var inputString = input.ToLower();

        int result = 0;
        for (int i = 0; i < inputString.Length; i++)
        {
            result *= AcceptedCharacters.Length;
            var character = inputString[i];
            result += AcceptedCharacters.IndexOf(character);
        }
        return result;
    }

    public static int Decode(char data)
    {
        return Decode(data.ToString());
    }
}

这是我用过的测试。使用Should断言库进行MS测试。

[TestClass]
public class ZBase32EncoderTests
{

    [TestMethod]
    public void Encoding_0_ReturnsFirstCharacter()
    {
        var result = ZBase32Encoder.Encode(0);
        result.ShouldEqual(ZBase32Encoder.AcceptedCharacters[0].ToString());
    }

    [TestMethod]
    public void Encoding_1_ReturnsSecondCharacter()
    {
        var result = ZBase32Encoder.Encode(1);
        result.ShouldEqual(ZBase32Encoder.AcceptedCharacters[1].ToString());
    }

    [TestMethod]
    public void Encoding_32_ReturnsSecondAndFirstValues()
    {
        var result = ZBase32Encoder.Encode(32);
        result.ShouldEqual(ZBase32Encoder.AcceptedCharacters[1].ToString() + ZBase32Encoder.AcceptedCharacters[0].ToString());
    }

    [TestMethod]
    public void Encoding_64_ReturnsThirdAndFirstValues()
    {
        var result = ZBase32Encoder.Encode(64);
        result.ShouldEqual(ZBase32Encoder.AcceptedCharacters[2].ToString() + ZBase32Encoder.AcceptedCharacters[0].ToString());
    }

    [TestMethod]
    public void Encoding_65_ReturnsThirdAndSecondValues()
    {
        var result = ZBase32Encoder.Encode(65);
        result.ShouldEqual(ZBase32Encoder.AcceptedCharacters[2].ToString() + ZBase32Encoder.AcceptedCharacters[1].ToString());
    }



    [TestMethod]
    public void Decoding_FirstCharacter_Returns_0()
    {
        var inputCharacter = ZBase32Encoder.AcceptedCharacters[0];
        var result = ZBase32Encoder.Decode(inputCharacter);
        result.ShouldEqual(0);
    }

    [TestMethod]
    public void Decoding_SecondCharacter_Returns_1()
    {
        var inputCharacter = ZBase32Encoder.AcceptedCharacters[1];
        var result = ZBase32Encoder.Decode(inputCharacter);
        result.ShouldEqual(1);
    }

    [TestMethod]
    public void Decoding_SecondAndFirstValues_Shows_32()
    {
        var inputCharacters = ZBase32Encoder.AcceptedCharacters[1].ToString() + ZBase32Encoder.AcceptedCharacters[0];
        var result = ZBase32Encoder.Decode(inputCharacters);
        result.ShouldEqual(32);
    }

    [TestMethod]
    public void Decoding_ThirdAndFirstCharacters_Shows_64()
    {
        var inputCharacters = ZBase32Encoder.AcceptedCharacters[2].ToString() + ZBase32Encoder.AcceptedCharacters[0];
        var result = ZBase32Encoder.Decode(inputCharacters);
        result.ShouldEqual(64);
    }
}

答案 1 :(得分:4)

您可能想使用自己的编码/解码程序吗?

编码:

 string acceptedChar = "ABCDEFGHJKLMNPQRSTUWXZ0123456789";
 int yourNumber = 12345678;

 string response = "";
 while (yourNumber > 0)
 {
      response += acceptedChar[yourNumber % acceptedChar.Length];
      yourNumber /= acceptedChar.Length;
 }

解码:

 string acceptedChar = "ABCDEFGHJKLMNPQRSTUWXZ0123456789";
 string inputStr = "ABCD";

 int yourNumber = 0;
 for (int i = inputStr.Length; i > 0; i--)
 {
     yourNumber *= acceptedChar.Length;
     yourNumber += acceptedChar.IndexOf(inputStr[i]);
 }    

(未经测试的代码)

答案 2 :(得分:2)

如果查看手机键盘,可以使用这些字符(a,b,c),(w,x,y,z),(t,u,v)表示编号1985239,...尝试找到一种算法,在给定一组有序的无序字符集的情况下生成或多或少的英语单词 - 这些将更容易记忆。

答案 3 :(得分:2)

BenMaddox的帖子略有改进(使用do-while):

public static String encode(int num, String base) {
    String response = "";
    do{
        response = base.charAt(num % base.length()) + response;
        num /= base.length();
    } while(num>0); 
    return response;
}

答案 4 :(得分:1)

这个项目看起来像你想要的:

Base 36 type for .NET (C#)