Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/317.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# Base32解码_C#_.net_Base32 - Fatal编程技术网

C# Base32解码

C# Base32解码,c#,.net,base32,C#,.net,Base32,我有一个base32字符串,需要将其转换为字节数组。我在.NET framework中找不到转换方法。我可以找到base64的方法,但找不到base32的方法 Convert.FromBase64String–对于base32来说,类似这样的东西是完美的 框架中有这样一种方法吗?还是我必须使用自己的方法?检查此FromBase32String找到的.NET实现 编辑:上面的链接已失效;您可以在以下位置找到存档副本: 实际代码为: using System; using System.Text;

我有一个base32字符串,需要将其转换为字节数组。我在.NET framework中找不到转换方法。我可以找到base64的方法,但找不到base32的方法

Convert.FromBase64String
–对于base32来说,类似这样的东西是完美的


框架中有这样一种方法吗?还是我必须使用自己的方法?

检查此
FromBase32String
找到的.NET实现


编辑:上面的链接已失效;您可以在以下位置找到存档副本:

实际代码为:

using System;
using System.Text;

public sealed class Base32 {

      // the valid chars for the encoding
      private static string ValidChars = "QAZ2WSX3" + "EDC4RFV5" + "TGB6YHN7" + "UJM8K9LP";

      /// <summary>
      /// Converts an array of bytes to a Base32-k string.
      /// </summary>
      public static string ToBase32String(byte[] bytes) {
            StringBuilder sb = new StringBuilder();         // holds the base32 chars
            byte index;
            int hi = 5;
            int currentByte = 0;

            while (currentByte < bytes.Length) {
                  // do we need to use the next byte?
                  if (hi > 8) {
                        // get the last piece from the current byte, shift it to the right
                        // and increment the byte counter
                        index = (byte)(bytes[currentByte++] >> (hi - 5));
                        if (currentByte != bytes.Length) {
                              // if we are not at the end, get the first piece from
                              // the next byte, clear it and shift it to the left
                              index = (byte)(((byte)(bytes[currentByte] << (16 - hi)) >> 3) | index);
                        }

                        hi -= 3;
                  } else if(hi == 8) { 
                        index = (byte)(bytes[currentByte++] >> 3);
                        hi -= 3; 
                  } else {

                        // simply get the stuff from the current byte
                        index = (byte)((byte)(bytes[currentByte] << (8 - hi)) >> 3);
                        hi += 5;
                  }

                  sb.Append(ValidChars[index]);
            }

            return sb.ToString();
      }


      /// <summary>
      /// Converts a Base32-k string into an array of bytes.
      /// </summary>
      /// <exception cref="System.ArgumentException">
      /// Input string <paramref name="s">s</paramref> contains invalid Base32-k characters.
      /// </exception>
      public static byte[] FromBase32String(string str) {
            int numBytes = str.Length * 5 / 8;
            byte[] bytes = new Byte[numBytes];

            // all UPPERCASE chars
            str = str.ToUpper();

            int bit_buffer;
            int currentCharIndex;
            int bits_in_buffer;

            if (str.Length < 3) {
                  bytes[0] = (byte)(ValidChars.IndexOf(str[0]) | ValidChars.IndexOf(str[1]) << 5);
                  return bytes;
            }

            bit_buffer = (ValidChars.IndexOf(str[0]) | ValidChars.IndexOf(str[1]) << 5);
            bits_in_buffer = 10;
            currentCharIndex = 2;
            for (int i = 0; i < bytes.Length; i++) {
                  bytes[i] = (byte)bit_buffer;
                  bit_buffer >>= 8;
                  bits_in_buffer -= 8;
                  while (bits_in_buffer < 8 && currentCharIndex < str.Length) {
                        bit_buffer |= ValidChars.IndexOf(str[currentCharIndex++]) << bits_in_buffer;
                        bits_in_buffer += 5;
                  }
            }

            return bytes;
      }
}
使用系统;
使用系统文本;
公共密封类Base32{
//编码的有效字符
专用静态字符串ValidChars=“QAZ2WSX3”+“EDC4RFV5”+“TGB6YHN7”+“UJM8K9LP”;
/// 
///将字节数组转换为Base32-k字符串。
/// 
公共静态字符串ToBase32String(字节[]字节){
StringBuilder sb=new StringBuilder();//保存base32字符
字节索引;
int-hi=5;
int currentByte=0;
while(currentByte8){
//从当前字节中获取最后一个片段,将其向右移动
//并递增字节计数器
索引=(字节)(字节[currentByte++]>>(hi-5));
if(currentByte!=字节.长度){
//如果我们不在最后,从
//下一个字节,清除并向左移动
索引=(字节)((字节)(字节[currentByte]>3)|索引);
}
hi-=3;
}如果(hi==8){
索引=(字节)(字节[currentByte++]>>3);
hi-=3;
}否则{
//只需从当前字节获取内容
索引=(字节)((字节)(字节[currentByte]>3);
hi+=5;
}
sb.追加(有效字符[索引]);
}
使某人返回字符串();
}
/// 
///将Base32-k字符串转换为字节数组。
/// 
/// 
///输入字符串s包含无效的Base32-k字符。
/// 
base32string(string str)中的公共静态字节[]{
int numBytes=str.Length*5/8;
字节[]字节=新字节[numBytes];
//所有大写字符
str=str.ToUpper();
int位缓冲区;
int currentCharIndex;
缓冲区中的整数位;
如果(str.Length<3){
字节[0]=(字节)(ValidChars.IndexOf(str[0])| ValidChars.IndexOf(str[1])=8;
_缓冲器中的位_-=8;
while(缓冲区中的位<8&¤tCharIndexbit_buffer |=ValidChars.IndexOf(str[currentCharIndex++])这是我的快速速记解决方案。它只适用于8个base32字符的倍数的字符串。但确实有效

public class Base32
{
  /// <summary>
  /// Decode a Base32 string
  /// This will only work on a multiple of 40 bits (5 bytes)
  /// http://www.garykessler.net/library/base64.html
  /// </summary>
  public static byte[] Decode(string Base32String)
  {
    // Ignore hyphens
    string str = Base32String.Replace("-", "");

    // Convert it to bits
    List<byte> bits = new List<byte>();
    foreach (char c in str)
    {
      int i = CharToValue(c);
      bits.Add((byte)((i & 16) > 0 ? 1 : 0));
      bits.Add((byte)((i & 8) > 0 ? 1 : 0));
      bits.Add((byte)((i & 4) > 0 ? 1 : 0));
      bits.Add((byte)((i & 2) > 0 ? 1 : 0));
      bits.Add((byte)((i & 1) > 0 ? 1 : 0));
    }

    // Convert bits into bytes
    List<byte> bytes = new List<byte>();
    for (int i = 0; i < bits.Count; i += 8)
    {
      bytes.Add((byte)(
        (bits[i + 0] << 7) +
        (bits[i + 1] << 6) +
        (bits[i + 2] << 5) +
        (bits[i + 3] << 4) +
        (bits[i + 4] << 3) +
        (bits[i + 5] << 2) +
        (bits[i + 6] << 1) +
        (bits[i + 7] << 0)));
    }

    return bytes.ToArray();
  }

  static int CharToValue(char c)
  {
    char cl = char.ToLower(c);
    if (cl == 'a') return 0;
    if (cl == 'b') return 1;
    if (cl == 'c') return 2;
    if (cl == 'd') return 3;
    if (cl == 'e') return 4;
    if (cl == 'f') return 5;
    if (cl == 'g') return 6;
    if (cl == 'h') return 7;
    if (cl == 'i') return 8;
    if (cl == 'j') return 9;
    if (cl == 'k') return 10;
    if (cl == 'l') return 11;
    if (cl == 'm') return 12;
    if (cl == 'n') return 13;
    if (cl == 'o') return 14;
    if (cl == 'p') return 15;
    if (cl == 'q') return 16;
    if (cl == 'r') return 17;
    if (cl == 's') return 18;
    if (cl == 't') return 19;
    if (cl == 'u') return 20;
    if (cl == 'v') return 21;
    if (cl == 'w') return 22;
    if (cl == 'x') return 23;
    if (cl == 'y') return 24;
    if (cl == 'z') return 25;
    if (cl == '2') return 26;
    if (cl == '3') return 27;
    if (cl == '4') return 28;
    if (cl == '5') return 29;
    if (cl == '6') return 30;
    if (cl == '7') return 31;
    throw new Exception("Not a base32 string");
  }
}
公共类Base32
{
/// 
///解码Base32字符串
///这只适用于40位(5字节)的倍数
/// http://www.garykessler.net/library/base64.html
/// 
公共静态字节[]解码(字符串Base32String)
{
//忽略连字符
string str=Base32String.Replace(“-”,“”);
//将其转换为位
列表位=新列表();
foreach(str中的字符c)
{
int i=图表价值(c);
位加((字节)((i&16)>0?1:0));
位加((字节)((i&8)>0?1:0));
位加((字节)((i&4)>0?1:0));
位加((字节)((i&2)>0?1:0));
位加((字节)((i&1)>0?1:0));
}
//将位转换为字节
列表字节=新列表();
对于(int i=0;i(bits[i+0]我已经编写了各种Base32和Base64编码/解码方法的一些灵活的基于标准的实现。值得注意的是:base64url(根据rfc4648)及其Base32等价物

默认情况下,Base32Url类仅使用字符A到Z和2到7进行编码。不使用连字符、下划线、加号、斜杠或等号,使其在几乎所有情况下都可用作URL标记。Base32Url还支持自定义字母表、区分大小写/不区分大小写、填充/不填充等


我需要一个base32编码器/解码器,所以今天下午我花了几个小时来组装它。我相信它符合这里列出的标准:

公共类基类编码
{
公共静态字节[]到字节(字符串输入)
{
if(string.IsNullOrEmpty(输入))
{
抛出新的ArgumentNullException(“输入”);
}
input=input.TrimEnd('=');//删除填充字符
int byteCount=input.Length*5/8;//必须将其截断
字节[]返回数组=新字节[字节计数];
字节curByte=0,位保留=8;
int mask=0,arrayIndex=0;
foreach(输入中的字符c)
{
int c值=图表价值(c);
如果(位保留>5)
{
掩码=cValue>(5位保留);
corbyte=(字节)(corbyte |掩码);
returnArray[arrayIndex++]=corbyte;
curByte=(字节)(C值64)
{
返回值-65;
}
//50-55==数字2-7
如果(值<56&&值>49)
{
返回值-24;
}
//97-122==小写字母
如果(值<123&&value>96)
{
返回值-97;
}
抛出新ArgumentException(“字符不是Base32字符。”,“c”);
}
专用静态字符值TOCHAR(字节b)
{
如果(b<26)
{
返回(字符)
public class Base32Encoding
{
    public static byte[] ToBytes(string input)
    {
        if (string.IsNullOrEmpty(input))
        {
            throw new ArgumentNullException("input");
        }

        input = input.TrimEnd('='); //remove padding characters
        int byteCount = input.Length * 5 / 8; //this must be TRUNCATED
        byte[] returnArray = new byte[byteCount];

        byte curByte = 0, bitsRemaining = 8;
        int mask = 0, arrayIndex = 0;

        foreach (char c in input)
        {
            int cValue = CharToValue(c);

            if (bitsRemaining > 5)
            {
                mask = cValue << (bitsRemaining - 5);
                curByte = (byte)(curByte | mask);
                bitsRemaining -= 5;
            }
            else
            {
                mask = cValue >> (5 - bitsRemaining);
                curByte = (byte)(curByte | mask);
                returnArray[arrayIndex++] = curByte;
                curByte = (byte)(cValue << (3 + bitsRemaining));
                bitsRemaining += 3;
            }
        }

        //if we didn't end with a full byte
        if (arrayIndex != byteCount)
        {
            returnArray[arrayIndex] = curByte;
        }

        return returnArray;
    }

    public static string ToString(byte[] input)
    {
        if (input == null || input.Length == 0)
        {
            throw new ArgumentNullException("input");
        }

        int charCount = (int)Math.Ceiling(input.Length / 5d) * 8;
        char[] returnArray = new char[charCount];

        byte nextChar = 0, bitsRemaining = 5;
        int arrayIndex = 0;

        foreach (byte b in input)
        {
            nextChar = (byte)(nextChar | (b >> (8 - bitsRemaining)));
            returnArray[arrayIndex++] = ValueToChar(nextChar);

            if (bitsRemaining < 4)
            {
                nextChar = (byte)((b >> (3 - bitsRemaining)) & 31);
                returnArray[arrayIndex++] = ValueToChar(nextChar);
                bitsRemaining += 5;
            }

            bitsRemaining -= 3;
            nextChar = (byte)((b << bitsRemaining) & 31);
        }

        //if we didn't end with a full char
        if (arrayIndex != charCount)
        {
            returnArray[arrayIndex++] = ValueToChar(nextChar);
            while (arrayIndex != charCount) returnArray[arrayIndex++] = '='; //padding
        }

        return new string(returnArray);
    }

    private static int CharToValue(char c)
    {
        int value = (int)c;

        //65-90 == uppercase letters
        if (value < 91 && value > 64)
        {
            return value - 65;
        }
        //50-55 == numbers 2-7
        if (value < 56 && value > 49)
        {
            return value - 24;
        }
        //97-122 == lowercase letters
        if (value < 123 && value > 96)
        {
            return value - 97;
        }

        throw new ArgumentException("Character is not a Base32 character.", "c");
    }

    private static char ValueToChar(byte b)
    {
        if (b < 26)
        {
            return (char)(b + 65);
        }

        if (b < 32)
        {
            return (char)(b + 24);
        }

        throw new ArgumentException("Byte is not a value Base32 value.", "b");
    }

}
Option Compare Text
Imports System.ComponentModel

Public Structure Base32(Of T)

        Private Const csValidStandardBase32Chars As String = "0123456789ABCDEFGHIJKLMNOPQRSTUV"

        <EditorBrowsable(EditorBrowsableState.Never)> _
        Class Base32Nibble

                <EditorBrowsable(EditorBrowsableState.Never)> _
                Friend mStore As New BitArray(5, False)

                Public ReadOnly Property Value As Byte
                        Get
                                Dim result As Byte = 0
                                For index As Byte = 0 To mStore.Count - 1
                                        If mStore(index) Then
                                                result += (2 ^ index)
                                        End If
                                Next
                                Return result
                        End Get
                End Property

                Public Overrides Function ToString() As String
                        Dim nibbleString As String = Nothing
                        For Each bit As Boolean In mStore
                                nibbleString = Math.Abs(CInt(bit)).ToString() & nibbleString
                        Next
                        Return nibbleString
                End Function

        End Class

        Private Shared mNibbles As List(Of Base32Nibble)

        Public ReadOnly Property Count As Long
                Get
                        Return mNibbles.Count
                End Get
        End Property

        Default Public ReadOnly Property Item(ByVal index As Integer) As Base32Nibble
                Get
                        Return DirectCast(mNibbles(index), Base32Nibble)
                End Get
        End Property

        Public Sub New(ByVal Value As T)
                Dim temp As Object = CType(Value, T)
                getNibbles(BitConverter.GetBytes(temp))
        End Sub

        Public Sub New(ByVal Value As Byte())
                getNibbles(Value)
        End Sub

        Public Shared Widening Operator CType(ByVal Value As T) As Base32(Of T)
                Return New Base32(Of T)(Value)
        End Operator

        Public Shared Widening Operator CType(ByVal Value As Byte()) As Base32(Of T)
                Return New Base32(Of T)(Value)
        End Operator

        Public ReadOnly Property Value As String
                Get
                        Dim result As String = Nothing
                        For Each Nib As Base32(Of T).Base32Nibble In mNibbles
                                result = csValidStandardBase32Chars(Nib.Value) & result
                        Next
                        Return result.TrimStart("0")
                End Get
        End Property

        Public Function ToNumeric(ByVal Base32String As String) As T
                Dim result As T = CType(CType(0, Object), T)
                Try
                        If Base32String.Trim.Length > 0 Then
                                Dim pos As Integer = 0
                                Do
                                        Dim temp As Object = getBase32Value(Base32String, pos)
                                        result = result + temp
                                        pos += 1
                                Loop While (pos < Base32String.Length)
                        End If
                Catch ex As Exception
                        ' Catch overflow errors if the generic type T doesn't have enough
                        ' room to store the result
                        System.Diagnostics.Debug.Print(ex.Message)
                End Try
                Return result
        End Function

        Private Shared Sub getNibbles(ByVal Value As Byte())

                Dim valueBytes As New BitArray(Value)
                Dim nib As Base32Nibble = Nothing

                mNibbles = New List(Of Base32Nibble)

                Dim padding As Byte = (1 - (valueBytes.Length / 5 - (valueBytes.Length \ 5))) * 5
                valueBytes.Length = valueBytes.Length + padding

                For element As Short = 0 To valueBytes.Count - 1
                        If (element Mod 5 = 0) Then
                                nib = New Base32Nibble()
                                mNibbles.Add(nib)
                        End If
                        nib.mStore.Item(element Mod 5) = valueBytes.Item(element)
                Next

        End Sub

        Private Function getBase32Char(ByVal InputString As String, ByVal InputPosition As Integer) As String
                Return csValidStandardBase32Chars.IndexOf(Mid(InputString, InputPosition + 1, 1))
        End Function

        Private Function getBase32Value(ByVal InputString As String, ByVal InputPosition As Integer) As T
                Return CType(CType((getBase32Char(InputString, InputPosition) * (32 ^ (InputString.Length - 1 - InputPosition))), Object), T)
        End Function

End Structure
Dim value As Base32(Of Int64) = 123456789
Console.WriteLine( "123456789 in Base32 = " & value.Value)
public static string BytesToBase32(byte[] bytes) {
    const string alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567";
    string output = "";
    for (int bitIndex = 0; bitIndex < bytes.Length * 8; bitIndex += 5) {
        int dualbyte = bytes[bitIndex / 8] << 8;
        if (bitIndex / 8 + 1 < bytes.Length)
            dualbyte |= bytes[bitIndex / 8 + 1];
        dualbyte = 0x1f & (dualbyte >> (16 - bitIndex % 8 - 5));
        output += alphabet[dualbyte];
    }

    return output;
}

public static byte[] Base32ToBytes(string base32) {
    const string alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567";
    List<byte> output = new List<byte>();
    char[] bytes = base32.ToCharArray();
    for (int bitIndex = 0; bitIndex < base32.Length * 5; bitIndex += 8) {
        int dualbyte = alphabet.IndexOf(bytes[bitIndex / 5]) << 10;
        if (bitIndex / 5 + 1 < bytes.Length)
            dualbyte |= alphabet.IndexOf(bytes[bitIndex / 5 + 1]) << 5;
        if (bitIndex / 5 + 2 < bytes.Length)
            dualbyte |= alphabet.IndexOf(bytes[bitIndex / 5 + 2]);

        dualbyte = 0xff & (dualbyte >> (15 - bitIndex % 5 - 8));
        output.Add((byte)(dualbyte));
    }
    return output.ToArray();
}
Base32Encoding.ToBytes("(your base 32 string here)")
Base32Encoding.ToString(new byte[] { /* your bytes here */ })