Skip to content

Releases: Tochemey/NetCore8583

v2.5.0

04 Apr 19:34
Immutable release. Only release title and notes can be modified.

Choose a tag to compare

Highlights

This release introduces EMV TLV (Tag-Length-Value) support for chip card data, enabling first-class parsing, building, and integration of BER-TLV encoded data -- commonly carried in ISO 8583 field 55. The implementation follows the EMV v4.3 Specification and ISO/IEC 8825-1 BER encoding rules.

New Features

  • TlvParser -- Parses BER-TLV encoded byte arrays into structured TlvTag records. Handles single-byte tags, multi-byte tags (2-3+ bytes), short-form and long-form lengths, constructed (nested) tags, and inter-TLV padding bytes (0x00, 0xFF).

  • TlvBuilder -- Fluent API for constructing BER-TLV byte sequences:

    byte[] data = new TlvBuilder()
        .AddTag("9F26", cryptogramValue)
        .AddTag("9F27", cidValue)
        .Build();
  • TlvTag -- Immutable record type representing a single TLV data object with Tag (hex string), Length, Value (byte array), and optional Description. Supports IsConstructed detection and GetNestedTags() for constructed data objects.

  • EmvTags -- Built-in FrozenDictionary of 38 common EMV tag descriptions sourced from EMV v4.3 Book 3 (Annex A) and ISO/IEC 7816-4, with case-insensitive lookup. Spec version exposed via EmvTags.SpecVersion.

  • TlvField -- ICustomBinaryField implementation that allows field 55 (or any field) to be registered as a TLV-aware composite field in both XML and programmatic (MessageFactoryBuilder) configurations.

  • IsoMessage TLV extension methods -- Convenience helpers for field 55 access:

    • GetTlvTags() -- retrieve parsed TLV tags
    • SetTlvTags() -- set TLV tags on the message
    • GetTlvBytes() -- retrieve raw TLV bytes
    • FindTlvTag(string tag) -- find a specific tag by hex identifier

Improvements

  • Expanded test coverage: Added new test classes with comprehensive unit tests covering single-byte tags, multi-byte tags, nested constructed tags, round-trip encode/decode, TlvField integration, IsoMessage extension methods, and EmvTags dictionary validation.
  • MIT license headers Added to all C# source files across the entire solution.
  • Documentation: Comprehensive README section covering BER-TLV encoding rules, standalone usage, XML and programmatic configuration, and IsoMessage extension methods, with a full EMV tag reference table.

Bug Fixes

  • Fixed date/time related test failures.

Supported Frameworks

  • .NET 8.0
  • .NET 9.0
  • .NET 10.0

Pull Requests

  • test: add tests to validate a bug reported sometime ago by @Tochemey in #45
  • feat: ✨ add emv v4.3 field 55 parser support by @Tochemey in #47

Full Changelog: 2.4.0...v2.5.0

2.4.0

16 Feb 00:12
Immutable release. Only release title and notes can be modified.

Choose a tag to compare

🚀 What's Changed

✨ Fluent Message Factory Builder API

  • Code-first configuration without XML — a new MessageFactoryBuilder<T> provides a fluent, type-safe API for constructing fully-configured MessageFactory instances entirely in code.
  • 🧩 Supports all configuration options previously available only through XML: headers, templates, parse maps, custom fields, composite fields, and all factory properties.
  • 🔗 Template and parse-map inheritance via Extends(), with field-level override and exclusion support.
  • 🏗️ New builder classes: MessageFactoryBuilder<T>, TemplateBuilder, ParseMapBuilder, and CompositeFieldBuilder.
var factory = new MessageFactoryBuilder<IsoMessage>()
    .WithEncoding(Encoding.UTF8)
    .WithHeader(0x0200, "ISO")
    .WithTemplate(0x0200, t => t
        .Field(3, IsoType.NUMERIC, "000000", 6)
        .Field(11, IsoType.NUMERIC, "000001", 6)
        .Field(41, IsoType.ALPHA, "TERMINAL", 8))
    .WithTemplate(0x0210, t => t
        .Extends(0x0200)
        .Field(39, IsoType.ALPHA, "00", 2))
    .WithParseMap(0x0200, p => p
        .Field(3, IsoType.NUMERIC, 6)
        .Field(11, IsoType.NUMERIC, 6)
        .Field(41, IsoType.ALPHA, 8))
    .WithParseMap(0x0210, p => p
        .Extends(0x0200)
        .Field(39, IsoType.ALPHA, 2))
    .Build();

📎 PR: #42

⚡ Performance: Zero-Copy Parsing, Span<T>, Bitmap128 & Allocation Reductions

  • 🧮 Bitmap128 struct backed by UInt128 replaces BitArray for field-presence tracking — significantly faster bit operations with zero heap allocations.
  • 🔬 Span<T> and ReadOnlySpan<T> used throughout parsing and encoding, enabling zero-copy byte/string conversions and eliminating intermediate array allocations.
  • 🔄 Zero-copy byte utilities (Bytes extensions) using MemoryMarshal.Cast for reinterpreting between byte[] and sbyte[] without copying.
  • 🧵 Stringx extensions with GetSignedBytes() overloads that encode directly into destination buffers, plus ArrayPool<T> pooled variants for hot paths.
  • 💾 EncodingCache to avoid repeated encoding lookups.
  • 📦 Reorganised internal utilities from NetCore8583.UtilNetCore8583.Extensions namespace for clearer separation.
  • 🔧 All field parsers, IsoMessage, IsoValue, MessageFactory, and codec classes updated to use the new span-based APIs.

📎 PR: #41

⚠️ Breaking Changes

  • The NetCore8583.Util namespace has been reorganised into NetCore8583.Extensions. If you reference types like HexCodec, Bcd, Arrays, OsUtil, Enumm, DictionaryExtensions, or ParseException directly, update your using statements accordingly.
  • 🗑️ Removed: ByteUtil, DateUtil, StringUtil, DictionaryExtensions, Enumm, and ParseException from NetCore8583.Util (replaced by equivalents in NetCore8583.Extensions).

Full Changelog: 2.3.0...2.4.0

2.3.0

05 Feb 22:11
805627d

Choose a tag to compare

🚀 What’s Changed

✨ Features

  • Add support for .NET 10
    Includes test fixes to ensure compatibility and stability.
    Thanks to @fernandoareias 🙌
    #37

🧹 Maintenance

  • Upgrade dependencies & sunset legacy frameworks
    • Updated project dependencies to their latest compatible versions
    • Dropped support for .NET 6 and .NET 7 (now end-of-life / nearing EOL)
      #39

⚠️ Breaking Changes

  • Support for .NET 6 and .NET 7 has been removed.
    Please upgrade to a supported .NET version before updating.

👋 New Contributors

  • 🎉 @fernandoareias made their first contribution!
    Thanks for helping move the project forward 💙
    #37

Full Changelog: 2.2.2...2.3.0

2.2.2

17 Feb 20:57
eb5e17e

Choose a tag to compare

What's Changed

Full Changelog: 2.2.1...2.2.2

2.2.1

16 Dec 17:10

Choose a tag to compare

What's Changed

  • feat: add ILogger interface that can be implemented by @Tochemey in #27
  • fix: create unconfigured response message by @TadijaB in #29

New Contributors

Full Changelog: 2.2.0...2.2.1

2.2.0

10 May 08:24

Choose a tag to compare

What's Changed

New Contributors

Full Changelog: 2.1.0...2.2.0

2.1.0

15 Sep 02:51
36b353c

Choose a tag to compare

What's Changed

Full Changelog: 2.0.0...2.1.0

2.0.0

14 Feb 11:44

Choose a tag to compare

What's Changed

  • Upgrade to Net 6.0

1.0.3

07 Aug 22:49
20bdd45

Choose a tag to compare

Noteworthy

  • CopyFieldsFrom added to IsoMessage to copy specific fields from one message to another
  • RemoveFields added to IsoMessage remove specific fields from message
  • ToUnsignedBytes has been renamed to ToUint8
  • ToSignedBytes has been renamed to ToInt8

1.0.2

02 Jan 21:57

Choose a tag to compare

Noteworthy

  • Upgraded to NET 5.0
  • Bug fixing in LLLBinParseInfo
  • Bug fix: 128th field in referenced template is missing when using extends in template element
  • Bug fix: LLLLBIN length calculation when element is more than 1000 bytes
  • Configurable radix for integer parsing.
  • New behavior for MessageFactory.createResponse(): The new behavior for the createResponse method within the MessageFactory class (while preserving the existing one), in order to be able to create a response with only the fields in the template, overriding the values with the contents of the request only for those fields.