Pay*_*aya 12 .net c# algorithm base64 encoding
我有一个字节数组(任意长度),我想用我自己的基本编码器将这个数组编码成字符串.In .NET是标准Base64编码器,但如果我想对数组进行编码Base62,Base53或者Base13?
甚至可以创建这样的通用基础编码器?
我知道我可以用简单的方法做到这一点,也就是说,对于每个字节保留固定数量的字符(如果是Base62,那将是5个字符),并做直接字节 - >字符编码,但我会浪费空间,因为5个Base62字符可以包含多于1个字节,但少于2个字节.
我应该怎么写这样的编码器?或者已经有一些课程了吗?
请注意我也需要通用解码器,否则这对我来说没用.
由于该解决方案已经知道(使用BigInteger),我只想在这里提供一些与BigInteger该类相关的资源,因为它在.NET 3.5中不可用:
C#中的大整数
http://intx.codeplex.com/
https://svn.apache.org/repos/asf/incubator/heraldry/libraries/csharp/openid/trunk/Mono/Mono.Math/BigInteger.cs
http ://www.codeproject.com/KB/cs/BigInteger_Library.aspx
http://www.codeproject.com/KB/cs/biginteger.aspx
Ter*_*ver 11
派对有点晚了,但......
因为您的规范要求任意数量的位,所以必须具有可以使用任意位数的整数类型.如果您无法定位.NET 4.0,则必须在某处(例如.NET 4.0)乞讨,借用或窃取BigInteger实现.
public static class GenericBaseConverter
{
public static string ConvertToString(byte[] valueAsArray, string digits, int pad)
{
if (digits == null)
throw new ArgumentNullException("digits");
if (digits.Length < 2)
throw new ArgumentOutOfRangeException("digits", "Expected string with at least two digits");
BigInteger value = new BigInteger(valueAsArray);
bool isNeg = value < 0;
value = isNeg ? -value : value;
StringBuilder sb = new StringBuilder(pad + (isNeg ? 1 : 0));
do
{
BigInteger rem;
value = BigInteger.DivRem(value, digits.Length, out rem);
sb.Append(digits[(int)rem]);
} while (value > 0);
// pad it
if (sb.Length < pad)
sb.Append(digits[0], pad - sb.Length);
// if the number is negative, add the sign.
if (isNeg)
sb.Append('-');
// reverse it
for (int i = 0, j = sb.Length - 1; i < j; i++, j--)
{
char t = sb[i];
sb[i] = sb[j];
sb[j] = t;
}
return sb.ToString();
}
public static BigInteger ConvertFromString(string s, string digits)
{
BigInteger result;
switch (Parse(s, digits, out result))
{
case ParseCode.FormatError:
throw new FormatException("Input string was not in the correct format.");
case ParseCode.NullString:
throw new ArgumentNullException("s");
case ParseCode.NullDigits:
throw new ArgumentNullException("digits");
case ParseCode.InsufficientDigits:
throw new ArgumentOutOfRangeException("digits", "Expected string with at least two digits");
case ParseCode.Overflow:
throw new OverflowException();
}
return result;
}
public static bool TryConvertFromString(string s, string digits, out BigInteger result)
{
return Parse(s, digits, out result) == ParseCode.Success;
}
private enum ParseCode
{
Success,
NullString,
NullDigits,
InsufficientDigits,
Overflow,
FormatError,
}
private static ParseCode Parse(string s, string digits, out BigInteger result)
{
result = 0;
if (s == null)
return ParseCode.NullString;
if (digits == null)
return ParseCode.NullDigits;
if (digits.Length < 2)
return ParseCode.InsufficientDigits;
// skip leading white space
int i = 0;
while (i < s.Length && Char.IsWhiteSpace(s[i]))
++i;
if (i >= s.Length)
return ParseCode.FormatError;
// get the sign if it's there.
BigInteger sign = 1;
if (s[i] == '+')
++i;
else if (s[i] == '-')
{
++i;
sign = -1;
}
// Make sure there's at least one digit
if (i >= s.Length)
return ParseCode.FormatError;
// Parse the digits.
while (i < s.Length)
{
int n = digits.IndexOf(s[i]);
if (n < 0)
return ParseCode.FormatError;
BigInteger oldResult = result;
result = unchecked((result * digits.Length) + n);
if (result < oldResult)
return ParseCode.Overflow;
++i;
}
// skip trailing white space
while (i < s.Length && Char.IsWhiteSpace(s[i]))
++i;
// and make sure there's nothing else.
if (i < s.Length)
return ParseCode.FormatError;
if (sign < 0)
result = -result;
return ParseCode.Success;
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
6097 次 |
| 最近记录: |