public byte[] Decrypt(string input) { byte newChar = 0x0; //填充新字所缺位元數 int leaNewCharBitCounter = FixedByteCounter; //拿來使用的位元組所剩的位元數 int reminderBitCounter = 0; //用剩下的位元組 byte reminderByte = 0x0; List <byte> result = new List <byte>(); //去掉padding input = input.Replace("=", ""); byte[] byteResult = new byte[input.Length]; //把base32alphabet結果轉換成byte array for (int k = 0; k < input.Length; k++) { byteResult[k] = Convert.ToByte(Base32Alphabet.IndexOf(input[k])); } for (int i = 0; i < byteResult.Length; i++) { //空出newChar所需的空間 newChar |= (reminderByte <<= (FixedByteCounter - reminderBitCounter)); //埴充newChar所缺的bit數 leaNewCharBitCounter -= reminderBitCounter; if (leaNewCharBitCounter > FixedDrawCounter) { newChar |= (byte)(byteResult[i] << (leaNewCharBitCounter - FixedDrawCounter)); leaNewCharBitCounter -= FixedDrawCounter; reminderBitCounter = 0; } else if (leaNewCharBitCounter == FixedDrawCounter) { newChar |= byteResult[i]; leaNewCharBitCounter = 0; reminderBitCounter = 0; } else if (leaNewCharBitCounter < FixedDrawCounter) { newChar |= (byte)(byteResult[i] >> (FixedDrawCounter - leaNewCharBitCounter)); reminderBitCounter = FixedDrawCounter - leaNewCharBitCounter; reminderByte = byteResult[i] &= Convert.ToByte(Math.Pow(2, reminderBitCounter) - 1); leaNewCharBitCounter = 0; } if (leaNewCharBitCounter == 0) { result.Add(newChar); newChar = 0x0; leaNewCharBitCounter = FixedByteCounter; } } return(result.ToArray()); }
/// <summary> /// Convert <paramref name="base32String"/> string to a byte array /// </summary> /// <param name="base32String">Base32 string to convert - must be at least two characters</param> public static Maybe <byte[]> FromBase32String(string base32String) { // Check if string is empty if (string.IsNullOrEmpty(base32String)) { return(Array.Empty <byte>()); } // Convert to upper-case var base32StringUpperCase = base32String.ToUpperInvariant(); // Prepare output byte array var outputBytes = new byte[base32StringUpperCase.Length * OutByteSize / InByteSize]; // Check the size if (outputBytes.Length == 0) { return(F.None <byte[], M.InputStringNotLongEnoughMsg>()); } // Position in the string var base32Position = 0; // Offset inside the character in the string var base32SubPosition = 0; // Position within outputBytes array var outputBytePosition = 0; // The number of bits filled in the current output byte var outputByteSubPosition = 0; // Normally we would iterate on the input array but in this case we actually iterate on the output array // We do it because output array doesn''t have overflow bits, while input does and it will cause output array overflow if we don''t stop in time while (outputBytePosition < outputBytes.Length) { // Look up current character in the dictionary to convert it to byte var currentBase32Byte = Base32Alphabet.IndexOf(base32StringUpperCase[base32Position]); // Check if found if (currentBase32Byte < 0) { return(F.None <byte[]>(new M.CharacterNotInBase32AlphabetMsg(base32String[base32Position]))); } // Calculate the number of bits we can extract out of current input character to fill missing bits in the output byte var bitsAvailableInByte = Math.Min(OutByteSize - base32SubPosition, InByteSize - outputByteSubPosition); // Make space in the output byte outputBytes[outputBytePosition] <<= bitsAvailableInByte; // Extract the part of the input character and move it to the output byte outputBytes[outputBytePosition] |= (byte)(currentBase32Byte >> (OutByteSize - (base32SubPosition + bitsAvailableInByte))); // Update current sub-byte position outputByteSubPosition += bitsAvailableInByte; // Check overflow if (outputByteSubPosition >= InByteSize) { // Move to the next byte outputBytePosition++; outputByteSubPosition = 0; } // Update current base32 byte completion base32SubPosition += bitsAvailableInByte; // Check overflow or end of input array if (base32SubPosition >= OutByteSize) { // Move to the next character base32Position++; base32SubPosition = 0; } } return(outputBytes); }
private byte[] FromBase32String(string base32String) { const int InByteSize = 8; const int OutByteSize = 5; const string Base32Alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567"; // Check if string is null if (base32String == null) { return(null); } // Check if empty else if (base32String == string.Empty) { return(new byte[0]); } // Convert to upper-case string base32StringUpperCase = base32String.ToUpperInvariant(); // Prepare output byte array byte[] outputBytes = new byte[base32StringUpperCase.Length * OutByteSize / InByteSize]; // Check the size if (outputBytes.Length == 0) { throw new ArgumentException("Specified string is not valid Base32 format because it doesn't have enough data to construct a complete byte array"); } // Position in the string int base32Position = 0; // Offset inside the character in the string int base32SubPosition = 0; // Position within outputBytes array int outputBytePosition = 0; // The number of bits filled in the current output byte int outputByteSubPosition = 0; // Normally we would iterate on the input array but in this case we actually iterate on the output array // We do it because output array doesn't have overflow bits, while input does and it will cause output array overflow if we don't stop in time while (outputBytePosition < outputBytes.Length) { // Look up current character in the dictionary to convert it to byte int currentBase32Byte = Base32Alphabet.IndexOf(base32StringUpperCase[base32Position]); // Check if found if (currentBase32Byte < 0) { throw new ArgumentException(string.Format("Specified string is not valid Base32 format because character \"{0}\" does not exist in Base32 alphabet", base32String[base32Position])); } // Calculate the number of bits we can extract out of current input character to fill missing bits in the output byte int bitsAvailableInByte = Math.Min(OutByteSize - base32SubPosition, InByteSize - outputByteSubPosition); // Make space in the output byte outputBytes[outputBytePosition] <<= bitsAvailableInByte; // Extract the part of the input character and move it to the output byte outputBytes[outputBytePosition] |= (byte)(currentBase32Byte >> (OutByteSize - (base32SubPosition + bitsAvailableInByte))); // Update current sub-byte position outputByteSubPosition += bitsAvailableInByte; // Check overflow if (outputByteSubPosition >= InByteSize) { // Move to the next byte outputBytePosition++; outputByteSubPosition = 0; } // Update current base32 byte completion base32SubPosition += bitsAvailableInByte; // Check overflow or end of input array if (base32SubPosition >= OutByteSize) { // Move to the next character base32Position++; base32SubPosition = 0; } } return(outputBytes); }