/// <summary> /// base32hex decoding as defined by RFC4648 /// http://rfc.net/rfc4648.html /// One property with this alphabet, which the base64 and base32 /// alphabets lack, is that encoded data maintains its sort order when /// the encoded data is compared bit-wise. /// </summary> /// <remarks> /// This is suitable for encoding sort keys in xml documents such /// that xslt 1 can produce a proper ordering. /// </remarks> public static byte[] FromBase32HexString(string base32, Base32FormattingOptions options) { byte[] decodeMap = CreateDecodeMap(base32hexAlphabet, false); return(FromBase32String(base32, decodeMap, options)); }
public static byte[] FromBase32String(string base32, Base32FormattingOptions options) { byte[] decodeMap = CreateDecodeMap(base32Alphabet, false); return FromBase32String(base32, decodeMap, options); }
/// <summary> /// base32hex encoding as defined by RFC4648 /// http://rfc.net/rfc4648.html /// One property with this alphabet, which the base64 and base32 /// alphabets lack, is that encoded data maintains its sort order when /// the encoded data is compared bit-wise. /// </summary> /// <remarks> /// This is suitable for encoding sort keys in xml documents such /// that xslt 1 can produce a proper ordering. /// </remarks> public static string ToBase32HexString(IEnumerable <byte> octets, Base32FormattingOptions options) { return(ToBase32String(octets, base32hexAlphabet, options)); }
private static string ToBase32String(IEnumerable <byte> octets, string base32alphabet, Base32FormattingOptions options) { if (octets == null) { throw new ArgumentNullException(); } bool shouldPadResult = (options & Base32FormattingOptions. InsertTrailingPadding) == Base32FormattingOptions.InsertTrailingPadding; StringBuilder result = new StringBuilder(); int paddingCharactersRequired = 0; // for every block of five octets, there are 8 characters IEnumerator <byte> octetEnumerator = octets.GetEnumerator(); while (octetEnumerator.MoveNext()) { //01234567 01234567 01234567 01234567 01234567 //01234 01234 0123 4 01 234 // 012 34 0 1234 01234 01234 // byte 0 byte b = octetEnumerator.Current; result.Append(base32alphabet[b >> 3]); int remainingBits = b << 2; if (!octetEnumerator.MoveNext()) { result.Append(base32alphabet[0x1f & remainingBits]); paddingCharactersRequired = 6; break; } // byte 1 b = octetEnumerator.Current; result.Append(base32alphabet[0x1f & (remainingBits | (b >> 6))]); result.Append(base32alphabet[0x1f & b >> 1]); remainingBits = b << 4; if (!octetEnumerator.MoveNext()) { result.Append(base32alphabet[0x1f & remainingBits]); paddingCharactersRequired = 4; break; } // byte 2 b = octetEnumerator.Current; result.Append(base32alphabet[0x1f & (remainingBits | (b >> 4))]); remainingBits = b << 1; if (!octetEnumerator.MoveNext()) { result.Append(base32alphabet[0x1f & remainingBits]); paddingCharactersRequired = 3; break; } // byte 3 b = octetEnumerator.Current; result.Append(base32alphabet[0x1f & (remainingBits | (b >> 7))]); result.Append(base32alphabet[0x1f & (b >> 2)]); remainingBits = b << 3; if (!octetEnumerator.MoveNext()) { result.Append(base32alphabet[0x1f & remainingBits]); paddingCharactersRequired = 1; break; } // byte 4 b = octetEnumerator.Current; result.Append(base32alphabet[0x1f & (remainingBits | (b >> 5))]); result.Append(base32alphabet[0x1f & b]); } if (shouldPadResult) { result.Append('=', paddingCharactersRequired); Debug.Assert(result.Length % 8 == 0); } return(result.ToString()); }
public static string ToBase32String(IEnumerable<byte> octets, Base32FormattingOptions options) { return ToBase32String(octets, base32Alphabet, options); }
private static byte[] FromBase32String(string base32, byte[] decodeMap, Base32FormattingOptions options) { if (base32 == null) { throw new ArgumentNullException("base32"); } if (decodeMap == null) { throw new ArgumentNullException("decodeMap"); } if (decodeMap.Length != 0x080) { throw new ArgumentException("decodeMap must have 128 slots"); } bool shouldBePadded = (options & Base32FormattingOptions.InsertTrailingPadding) == Base32FormattingOptions.InsertTrailingPadding; if (!shouldBePadded) { int i = base32.IndexOf('='); if (i != -1) { throw new ArgumentException(string.Format( "Invalid character at index {0}: \"=\"", i)); } } int remainder = base32.Length % 8; if (remainder > 0) { if (shouldBePadded || remainder == 1 || remainder == 3 || remainder == 6) { throw new ArgumentException("base32 not proper length"); } base32 = base32 + new string('=', 8 - remainder); } byte[] result = new byte[(base32.Length / 8) * 5]; byte[] x = new byte[8]; int pad = 0; for (int i = 0, k = 0; i < base32.Length; i += 8) { int j; for (j = 0; j < 8; ++j) { char a = base32[i + j]; if (a == '=') { x[j] = 0; pad++; continue; } else if (pad != 0) { throw new ArgumentException( string.Format( "Invalid character at index {0}: \"=\" (padding found in the middle of the input)", i + j - 1)); } if (a >= 0x80 || (x[j] = decodeMap[a]) == 0xff) { throw new ArgumentException(string.Format( "Invalid character at index {0}: \"{1}\"", i + j, a)); } } result[k++] = (byte)((x[0] << 3) | (x[1] >> 2)); result[k++] = (byte)((x[1] << 6) | (x[2] << 1) | (x[3] >> 4)); result[k++] = (byte)((x[3] << 4) | (x[4] >> 1)); result[k++] = (byte)((x[4] << 7) | (x[5] << 2) | (x[6] >> 3)); result[k++] = (byte)((x[6] << 5) | x[7]); } if (pad != 0) { if (pad == 1) { Array.Resize(ref result, result.Length - 1); } else if (pad == 3) { Array.Resize(ref result, result.Length - 2); } else if (pad == 4) { Array.Resize(ref result, result.Length - 3); } else if (pad == 6) { Array.Resize(ref result, result.Length - 4); } else { throw new ArgumentException( string.Format("Invalid padding of length {0}", pad)); } } return(result); }
/// <summary> /// Converts a byte-array to an RFC4648 (https://tools.ietf.org/html/rfc4648) Base32 string. /// </summary> /// <param name="input">The input byte-array.</param> /// <param name="options">Any of <see cref="Base32FormattingOptions"/> enumeration values.</param> /// <returns>The input byte-array encoded into a Base32 string, following the provided options.</returns> public static string ToBase32String(this byte[] input, Base32FormattingOptions options = Base32FormattingOptions.RequirePaddingCharacter) { string alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567="; if ((options & Base32FormattingOptions.CrockfordAlphabet) == Base32FormattingOptions.CrockfordAlphabet) { alphabet = "0123456789ABCDEFGHJKMNPQRSTVWXYZ="; } else if ((options & Base32FormattingOptions.Hex32Alphabet) == Base32FormattingOptions.Hex32Alphabet) { alphabet = "0123456789ABCDEFGHIJKLMNOPQRSTUV="; } else if ((options & Base32FormattingOptions.VowelSafeAlphabet) == Base32FormattingOptions.VowelSafeAlphabet) { alphabet = "0123456789bcdfhjkmnpqrtvxyDFGHJL="; } ExtendedStringBuilder workingResult = new ExtendedStringBuilder(); int originalLength = input.Length; int newLength = originalLength; if (input.Length % 5 != 0) { newLength += originalLength % 5; } byte[] workingSet = new byte[newLength]; for (int i = 0; i < originalLength; i++) { workingSet[i] = input[i]; } for (int g = 0; g < newLength / 5; g++) { int indexOffset = g * 5; int temp = (workingSet[indexOffset] & 0xF4) >> 3; workingResult += alphabet[temp]; temp = (workingSet[indexOffset] & 0x03) << 2; if (indexOffset + 1 < input.Length) { temp |= (workingSet[indexOffset + 1] & 0xC0) >> 6; workingResult += alphabet[temp]; temp = (workingSet[indexOffset + 1] & 0x3E) >> 1; workingResult += alphabet[temp]; temp = (workingSet[indexOffset + 1] & 0x01) << 4; if (indexOffset + 2 < input.Length) { temp |= (workingSet[indexOffset + 2] & 0xF0) >> 4; workingResult += alphabet[temp]; temp = (workingSet[indexOffset + 2] & 0x0F) << 1; if (indexOffset + 3 < input.Length) { temp |= (workingSet[indexOffset + 3] & 0x80) >> 7; workingResult += alphabet[temp]; temp = (workingSet[indexOffset + 3] & 0x7C) >> 2; workingResult += alphabet[temp]; temp = (workingSet[indexOffset + 3] & 0x03) << 3; if (indexOffset + 4 < input.Length) { temp |= (workingSet[indexOffset + 4] & 0xE0) >> 5; workingResult += alphabet[temp]; temp = workingSet[indexOffset + 4] & 0x1F; workingResult += alphabet[temp]; } else { workingResult += alphabet[temp]; if ((options & Base32FormattingOptions.RequirePaddingCharacter) == Base32FormattingOptions.RequirePaddingCharacter) { workingResult += alphabet[32]; } } } else { workingResult += alphabet[temp]; if ((options & Base32FormattingOptions.RequirePaddingCharacter) == Base32FormattingOptions.RequirePaddingCharacter) { workingResult += alphabet[32]; workingResult += alphabet[32]; workingResult += alphabet[32]; } } } else { workingResult += alphabet[temp]; if ((options & Base32FormattingOptions.RequirePaddingCharacter) == Base32FormattingOptions.RequirePaddingCharacter) { workingResult += alphabet[32]; workingResult += alphabet[32]; workingResult += alphabet[32]; workingResult += alphabet[32]; } } } else { workingResult += alphabet[temp]; if ((options & Base32FormattingOptions.RequirePaddingCharacter) == Base32FormattingOptions.RequirePaddingCharacter) { workingResult += alphabet[32]; workingResult += alphabet[32]; workingResult += alphabet[32]; workingResult += alphabet[32]; workingResult += alphabet[32]; workingResult += alphabet[32]; } } } if (((options & Base32FormattingOptions.RequirePaddingCharacter) == Base32FormattingOptions.RequirePaddingCharacter) && (originalLength != newLength)) { for (int padCount = 0; padCount < newLength - originalLength; padCount++) { workingResult += alphabet[32]; } } return(workingResult); }
private static string ToBase32String(IEnumerable<byte> octets, string base32alphabet, Base32FormattingOptions options) { if (octets == null) { throw new ArgumentNullException(); } bool shouldPadResult = (options & Base32FormattingOptions. InsertTrailingPadding) == Base32FormattingOptions.InsertTrailingPadding; StringBuilder result = new StringBuilder(); int paddingCharactersRequired = 0; // for every block of five octets, there are 8 characters IEnumerator<byte> octetEnumerator = octets.GetEnumerator(); while (octetEnumerator.MoveNext()) { //01234567 01234567 01234567 01234567 01234567 //01234 01234 0123 4 01 234 // 012 34 0 1234 01234 01234 // byte 0 byte b = octetEnumerator.Current; result.Append(base32alphabet[b >> 3]); int remainingBits = b << 2; if (!octetEnumerator.MoveNext()) { result.Append(base32alphabet[0x1f & remainingBits]); paddingCharactersRequired = 6; break; } // byte 1 b = octetEnumerator.Current; result.Append(base32alphabet[0x1f & (remainingBits | (b >> 6))]); result.Append(base32alphabet[0x1f & b >> 1]); remainingBits = b << 4; if (!octetEnumerator.MoveNext()) { result.Append(base32alphabet[0x1f & remainingBits]); paddingCharactersRequired = 4; break; } // byte 2 b = octetEnumerator.Current; result.Append(base32alphabet[0x1f & (remainingBits | (b >> 4))]); remainingBits = b << 1; if (!octetEnumerator.MoveNext()) { result.Append(base32alphabet[0x1f & remainingBits]); paddingCharactersRequired = 3; break; } // byte 3 b = octetEnumerator.Current; result.Append(base32alphabet[0x1f & (remainingBits | (b >> 7))]); result.Append(base32alphabet[0x1f & (b >> 2)]); remainingBits = b << 3; if (!octetEnumerator.MoveNext()) { result.Append(base32alphabet[0x1f & remainingBits]); paddingCharactersRequired = 1; break; } // byte 4 b = octetEnumerator.Current; result.Append(base32alphabet[0x1f & (remainingBits | (b >> 5))]); result.Append(base32alphabet[0x1f & b]); } if (shouldPadResult) { result.Append('=', paddingCharactersRequired); Debug.Assert(result.Length % 8 == 0); } return result.ToString(); }
private static byte[] FromBase32String(string base32, byte[] decodeMap, Base32FormattingOptions options) { if (base32 == null) { throw new ArgumentNullException("base32"); } if (decodeMap == null) { throw new ArgumentNullException("decodeMap"); } if (decodeMap.Length != 0x080) { throw new ArgumentException("decodeMap must have 128 slots"); } bool shouldBePadded = (options & Base32FormattingOptions.InsertTrailingPadding) == Base32FormattingOptions.InsertTrailingPadding; if (!shouldBePadded) { int i = base32.IndexOf('='); if (i != -1) { throw new ArgumentException(string.Format( "Invalid character at index {0}: \"=\"", i)); } } int remainder = base32.Length % 8; if (remainder > 0) { if (shouldBePadded || remainder == 1 || remainder == 3 || remainder == 6) { throw new ArgumentException("base32 not proper length"); } base32 = base32 + new string('=', 8 - remainder); } byte[] result = new byte[(base32.Length / 8) * 5]; byte[] x = new byte[8]; int pad = 0; for (int i = 0, k = 0; i < base32.Length; i += 8) { int j; for (j = 0;j < 8;++j) { char a = base32[i + j]; if (a == '=') { x[j] = 0; pad++; continue; } else if (pad != 0) { throw new ArgumentException( string.Format( "Invalid character at index {0}: \"=\" (padding found in the middle of the input)", i + j - 1)); } if (a >= 0x80 || (x[j] = decodeMap[a]) == 0xff) { throw new ArgumentException(string.Format( "Invalid character at index {0}: \"{1}\"", i + j, a)); } } result[k++] = (byte) ((x[0] << 3) | (x[1] >> 2)); result[k++] = (byte) ((x[1] << 6) | (x[2] << 1) | (x[3] >> 4)); result[k++] = (byte) ((x[3] << 4) | (x[4] >> 1)); result[k++] = (byte) ((x[4] << 7) | (x[5] << 2) | (x[6] >> 3)); result[k++] = (byte) ((x[6] << 5) | x[7]); } if (pad != 0) { if (pad == 1) { Array.Resize(ref result, result.Length - 1); } else if (pad == 3) { Array.Resize(ref result, result.Length - 2); } else if (pad == 4) { Array.Resize(ref result, result.Length - 3); } else if (pad == 6) { Array.Resize(ref result, result.Length - 4); } else { throw new ArgumentException( string.Format("Invalid padding of length {0}", pad)); } } return result; }
/// <summary> /// Converts a byte-array to an RFC4648 (https://tools.ietf.org/html/rfc4648) Base32 string. /// </summary> /// <param name="input">The input byte-array.</param> /// <param name="options">Any of <see cref="Base32FormattingOptions"/> enumeration values.</param> /// <returns>The input byte-array encoded into a Base32 string, following the provided options.</returns> public static string ToBase32String(this byte[] input, Base32FormattingOptions options = Base32FormattingOptions.RequirePaddingCharacter) { string alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567="; if ((options & Base32FormattingOptions.CrockfordAlphabet) == Base32FormattingOptions.CrockfordAlphabet) { alphabet = "0123456789ABCDEFGHJKMNPQRSTVWXYZ="; } else if ((options & Base32FormattingOptions.Hex32Alphabet) == Base32FormattingOptions.Hex32Alphabet) { alphabet = "0123456789ABCDEFGHIJKLMNOPQRSTUV="; } else if ((options & Base32FormattingOptions.VowelSafeAlphabet) == Base32FormattingOptions.VowelSafeAlphabet) { alphabet = "0123456789bcdfhjkmnpqrtvxyDFGHJL="; } ExtendedStringBuilder workingResult = new ExtendedStringBuilder(); int originalLength = input.Length; int newLength = originalLength; if (input.Length % 5 != 0) { newLength += originalLength % 5; } byte[] workingSet = new byte[newLength]; for (int i = 0; i < originalLength; i++) { workingSet[i] = input[i]; } for (int g = 0; g < newLength / 5; g++) { int indexOffset = g * 5; int temp = (workingSet[indexOffset] & 0xF4) >> 3; workingResult += alphabet[temp]; temp = (workingSet[indexOffset] & 0x03) << 2; if (indexOffset + 1 < input.Length) { temp |= (workingSet[indexOffset + 1] & 0xC0) >> 6; workingResult += alphabet[temp]; temp = (workingSet[indexOffset + 1] & 0x3E) >> 1; workingResult += alphabet[temp]; temp = (workingSet[indexOffset + 1] & 0x01) << 4; if (indexOffset + 2 < input.Length) { temp |= (workingSet[indexOffset + 2] & 0xF0) >> 4; workingResult += alphabet[temp]; temp = (workingSet[indexOffset + 2] & 0x0F) << 1; if (indexOffset + 3 < input.Length) { temp |= (workingSet[indexOffset + 3] & 0x80) >> 7; workingResult += alphabet[temp]; temp = (workingSet[indexOffset + 3] & 0x7C) >> 2; workingResult += alphabet[temp]; temp = (workingSet[indexOffset + 3] & 0x03) << 3; if (indexOffset + 4 < input.Length) { temp |= (workingSet[indexOffset + 4] & 0xE0) >> 5; workingResult += alphabet[temp]; temp = workingSet[indexOffset + 4] & 0x1F; workingResult += alphabet[temp]; } else { workingResult += alphabet[temp]; if ((options & Base32FormattingOptions.RequirePaddingCharacter) == Base32FormattingOptions.RequirePaddingCharacter) { workingResult += alphabet[32]; } } } else { workingResult += alphabet[temp]; if ((options & Base32FormattingOptions.RequirePaddingCharacter) == Base32FormattingOptions.RequirePaddingCharacter) { workingResult += alphabet[32]; workingResult += alphabet[32]; workingResult += alphabet[32]; } } } else { workingResult += alphabet[temp]; if ((options & Base32FormattingOptions.RequirePaddingCharacter) == Base32FormattingOptions.RequirePaddingCharacter) { workingResult += alphabet[32]; workingResult += alphabet[32]; workingResult += alphabet[32]; workingResult += alphabet[32]; } } } else { workingResult += alphabet[temp]; if ((options & Base32FormattingOptions.RequirePaddingCharacter) == Base32FormattingOptions.RequirePaddingCharacter) { workingResult += alphabet[32]; workingResult += alphabet[32]; workingResult += alphabet[32]; workingResult += alphabet[32]; workingResult += alphabet[32]; workingResult += alphabet[32]; } } } if (((options & Base32FormattingOptions.RequirePaddingCharacter) == Base32FormattingOptions.RequirePaddingCharacter) && (originalLength != newLength)) { for (int padCount = 0; padCount < newLength - originalLength; padCount++) { workingResult += alphabet[32]; } } return workingResult; }