Пример #1
0
        public static unsafe string Encode([NotNull] byte[] data)
        {
            // ReSharper disable once ConditionIsAlwaysTrueOrFalse
            // ReSharper disable once HeuristicUnreachableCode
            if (data == null)
            {
                return(null);
            }

            var size        = data.Length;
            var encodedSize = Z85Size.CalculateEncodedSize(size);
            var destination = new string('0', encodedSize);
            int charNbr     = 0;
            int byteNbr     = 0;

            const uint divisor4 = 85 * 85 * 85 * 85;
            const uint divisor3 = 85 * 85 * 85;
            const uint divisor2 = 85 * 85;
            const uint divisor1 = 85;
            const int  byte3    = 256 * 256 * 256;
            const int  byte2    = 256 * 256;
            const int  byte1    = 256;

            // Get pointers to avoid unnecessary range checking
            fixed(char *z85Encoder = Map.Encoder)
            fixed(char *z85Dest = destination)
            {
                while (byteNbr < size)
                {
                    // Accumulate value in base 256 (binary)
                    var value = (uint)((data[byteNbr + 0] * byte3) +
                                       (data[byteNbr + 1] * byte2) +
                                       (data[byteNbr + 2] * byte1) +
                                       data[byteNbr + 3]);
                    byteNbr += 4;

                    // Output value in base 85
                    z85Dest[charNbr + 0] = z85Encoder[(value / divisor4) % 85];
                    z85Dest[charNbr + 1] = z85Encoder[(value / divisor3) % 85];
                    z85Dest[charNbr + 2] = z85Encoder[(value / divisor2) % 85];
                    z85Dest[charNbr + 3] = z85Encoder[(value / divisor1) % 85];
                    z85Dest[charNbr + 4] = z85Encoder[value % 85];
                    charNbr += 5;
                }
            }

            return(destination);
        }
Пример #2
0
        public static unsafe byte[] Decode([NotNull] string input)
        {
            // ReSharper disable once ConditionIsAlwaysTrueOrFalse
            // ReSharper disable once HeuristicUnreachableCode
            if (input == null)
            {
                return(null);
            }

            var len         = input.Length;
            var decodedSize = Z85Size.CalculateDecodedSize(len);
            var decoded     = new byte[decodedSize];
            var byteNbr     = 0;
            var charNbr     = 0;

            const uint divisor3 = 256 * 256 * 256;
            const uint divisor2 = 256 * 256;
            const uint divisor1 = 256;

            // Get a pointers to avoid unnecessary range checking
            fixed(byte *z85Decoder = Map.Decoder)
            fixed(char *src = input)
            {
                while (charNbr < len)
                {
                    // Accumulate value in base 85
                    uint value = z85Decoder[(byte)src[charNbr]];
                    value    = (value * 85) + z85Decoder[(byte)src[charNbr + 1]];
                    value    = (value * 85) + z85Decoder[(byte)src[charNbr + 2]];
                    value    = (value * 85) + z85Decoder[(byte)src[charNbr + 3]];
                    value    = (value * 85) + z85Decoder[(byte)src[charNbr + 4]];
                    charNbr += 5;

                    // Output value in base 256
                    decoded[byteNbr + 0] = (byte)((value / divisor3) % 256);
                    decoded[byteNbr + 1] = (byte)((value / divisor2) % 256);
                    decoded[byteNbr + 2] = (byte)((value / divisor1) % 256);
                    decoded[byteNbr + 3] = (byte)(value % 256);
                    byteNbr += 4;
                }
            }

            return(decoded);
        }