Example #1
0
 /// <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));
 }
Example #2
0
		public static byte[] FromBase32String(string base32, Base32FormattingOptions options)
		{
			byte[] decodeMap = CreateDecodeMap(base32Alphabet, false);
			return FromBase32String(base32, decodeMap, options);
		}
Example #3
0
 /// <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));
 }
Example #4
0
        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());
        }
Example #5
0
		public static string ToBase32String(IEnumerable<byte> octets, Base32FormattingOptions options)
		{
			return ToBase32String(octets, base32Alphabet, options);
		}
Example #6
0
        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);
        }
Example #7
0
        /// <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);
        }
Example #8
0
		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();
		}
Example #9
0
		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;
		}
Example #10
0
        /// <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;
        }