protected override byte[] DecodeDataCore(string encoded, out Bech32EncodingType encodingType) { if (encoded == null) { throw new ArgumentNullException(nameof(encoded)); } CheckCase(encoded); var buffer = DataEncoders.Encoders.ASCII.DecodeData(encoded); if (buffer.Any(b => b < 33 || b > 126)) { throw new FormatException("bech chars are out of range"); } encoded = encoded.ToLowerInvariant(); buffer = DataEncoders.Encoders.ASCII.DecodeData(encoded); var pos = encoded.LastIndexOf("1", StringComparison.OrdinalIgnoreCase); if (encoded.Length > 1000 || pos == -1 || pos == 0 || pos + 13 > encoded.Length) { // ELEMENTS: 90->1000, 7->13 throw new FormatException("blech missing separator, separator misplaced or too long input"); } if (buffer.Skip(pos + 1).Any(x => !Byteset.Contains(x))) { throw new FormatException("bech chars are out of range"); } buffer = DataEncoders.Encoders.ASCII.DecodeData(encoded); var hrp = DataEncoders.Encoders.ASCII.DecodeData(encoded.Substring(0, pos)); if (!hrp.SequenceEqual(_Hrp)) { throw new FormatException("Mismatching human readable part"); } #if HAS_SPAN Span <byte> data = encoded.Length - pos - 1 is int l && l > 256 ? new byte[l] : stackalloc byte[l]; #else var data = new byte[encoded.Length - pos - 1]; #endif for (int j = 0, i = pos + 1; i < encoded.Length; i++, j++) { data[j] = (byte)Array.IndexOf(Byteset, buffer[i]); } if (!VerifyChecksum(data, encoded.Length, out encodingType, out var _)) { throw new FormatException("Error while verifying Blech32 checksum"); } #if HAS_SPAN return(data.Slice(0, data.Length - 12).ToArray()); #else return(data.Take(data.Length - 12).ToArray()); #endif }
protected override bool VerifyChecksum(byte[] data, int bechStringLen, out Bech32EncodingType encodingType, out int[] errorPosition) #endif { #if HAS_SPAN Span <byte> values = _HrpExpand.Length + data.Length is int v && v > 256 ? new byte[v] : stackalloc byte[v]; _HrpExpand.CopyTo(values); data.CopyTo(values.Slice(_HrpExpand.Length)); #else var values = _HrpExpand.Concat(data); #endif errorPosition = new int[0]; encodingType = Bech32EncodingType.BECH32; return(Polymod(values) == 1); }
public override string EncodeData(byte[] data, int offset, int count, Bech32EncodingType encodingType) #endif { #if HAS_SPAN Span <byte> combined = _Hrp.Length + 1 + data.Length + 12 is int v && v > 256 ? new byte[v] : stackalloc byte[v]; _Hrp.AsSpan().CopyTo(combined); #else var combined = new byte[_Hrp.Length + 1 + count + 12]; Array.Copy(_Hrp, 0, combined, 0, _Hrp.Length); #endif int combinedOffset = 0; combinedOffset += _Hrp.Length; combined[combinedOffset] = 49; combinedOffset++; #if HAS_SPAN data.CopyTo(combined.Slice(combinedOffset)); combinedOffset += data.Length; #else Array.Copy(data, offset, combined, combinedOffset, count); combinedOffset += count; #endif #if HAS_SPAN var checkSum = CreateChecksum(data); checkSum.AsSpan().Slice(0, 12).CopyTo(combined.Slice(combinedOffset)); for (int i = 0; i < data.Length + 12; i++) #else var checkSum = CreateChecksum(data, offset, count); Array.Copy(checkSum, 0, combined, combinedOffset, 12); for (int i = 0; i < count + 12; i++) #endif { combined[_Hrp.Length + 1 + i] = Byteset[combined[_Hrp.Length + 1 + i]]; } return(DataEncoders.Encoders.ASCII.EncodeData(combined)); }
public override string EncodeData(ReadOnlySpan <byte> data, Bech32EncodingType encodingType)
protected override bool VerifyChecksum(ReadOnlySpan <byte> data, int bechStringLen, out Bech32EncodingType encodingType, out int[] errorPosition)
protected override bool VerifyChecksum(byte[] data, int bechStringLen, out Bech32EncodingType encodingType, out int[] errorPosition) { return(VerifyChecksum(data.AsSpan(), bechStringLen, out encodingType, out errorPosition)); }