我需要编码/解码一个长达9位但通常长7位的整数。我想让沟通/记忆更容易 - 它将通过电话,复制和传播进行沟通。粘贴,从卡片/记忆/标签键入,手写在标签上并且通常被滥用!
我希望使用base 32方案减少位数(同时添加校验和)。我最赞成z-base-32(超过RFC4648实现),因为有些设计目标(例如手写)和字母表选择(小写,置换以支持更容易使用的字符)读,写,说,记得)。但是,我找不到C#实现,我担心从现有的Python实现移植。
有没有人有C#实现?或者,是否有人可以使用一组测试用例(规范中的示例除外)来验证端口?
我愿意接受有关替代编码方案的建议。
答案 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)
这个项目看起来像你想要的: