const byte PrefixByteUknown = 23 << 3; // Base32-encodes to 'X...' /// <summary> /// Decodes a base 32 encoded NKey into a nkey seed and verifies the checksum. /// </summary> /// <param name="src">Base 32 encoded Nkey.</param> /// <returns></returns> public static byte[] Decode(string src) { byte[] raw = Base32.Decode(src); ushort crc = (ushort)(raw[raw.Length - 2] | raw[raw.Length - 1] << 8); // trim off the CRC16 int len = raw.Length - 2; byte[] data = new byte[len]; Buffer.BlockCopy(raw, 0, data, 0, len); if (crc != Crc16.Checksum(data)) { throw new NATSException("Invalid CRC"); } return(data); }
internal static string Encode(byte prefixbyte, bool seed, byte[] src) { if (!IsValidPublicPrefixByte(prefixbyte)) { throw new NATSException("Invalid prefix"); } if (src.Length != 32) { throw new NATSException("Invalid seed size"); } MemoryStream stream = new MemoryStream(); if (seed) { // In order to make this human printable for both bytes, we need to do a little // bit manipulation to setup for base32 encoding which takes 5 bits at a time. byte b1 = (byte)(PrefixByteSeed | (prefixbyte >> 5)); byte b2 = (byte)((prefixbyte & 31) << 3); // 31 = 00011111 stream.WriteByte(b1); stream.WriteByte(b2); } else { stream.WriteByte(prefixbyte); } // write payload stream.Write(src, 0, src.Length); // Calculate and write crc16 checksum byte[] checksum = BitConverter.GetBytes(Crc16.Checksum(stream.ToArray())); stream.Write(checksum, 0, checksum.Length); return(Base32.Encode(stream.ToArray())); }