### Use Strongly-Typed EMV Tag Constants Source: https://context7.com/robonet/emvparser/llms.txt This example demonstrates using predefined constants for EMV tags, which enhances type safety and maintainability compared to using string literals. It includes examples of retrieving tags by constant, getting tag names, and handling potential errors. ```csharp using RoboNet.EMVParser; var emvData = "5F2A02097882021C009F26080123456789ABCDEF9F2701809F37040F00BA20"; var data = Convert.FromHexString(emvData); var tagsList = TLVParser.ParseTagsList(data); // Use EMVTags constants instead of magic strings var currencyTag = tagsList.GetTag(EMVTags.TransactionCurrencyCode); // instead of "5F2A" var cryptogramTag = tagsList.GetTag(EMVTags.ApplicationCryptogram); // instead of "9F26" var unpredictableNumberTag = tagsList.GetTag(EMVTags.UnpredictableNumber); // instead of "9F37" if (cryptogramTag != null) { Console.WriteLine($"Tag: {cryptogramTag.TagHex}"); Console.WriteLine($"Description: {EMVTags.GetTagName(cryptogramTag.TagHex)}"); Console.WriteLine($"Value: {cryptogramTag.ValueHex}"); } // Get tag descriptions for documentation string tagDescription = EMVTags.GetTagName("9F26"); Console.WriteLine($"Tag 9F26 is: {tagDescription}"); // Output: Application Cryptogram // Benefits: // 1. IntelliSense support in IDE // 2. Compile-time checking // 3. Prevents typos in tag names // 4. XML documentation for each constant // 5. Easier refactoring and code maintenance // Example with error handling try { var amountTag = tagsList.GetTag(EMVTags.AmountAuthorizedNumeric); if (amountTag != null) { long amount = amountTag.ValueNumeric; Console.WriteLine($"Transaction amount: {amount / 100.0:C}"); } } catch (Exception ex) { Console.WriteLine($"Error processing amount: {ex.Message}"); } ``` -------------------------------- ### Complex EMV Tag Usage Example in C# Source: https://github.com/robonet/emvparser/blob/main/docs/main.en.md A comprehensive example showing how to parse EMV data, retrieve a specific tag (Application Cryptogram) using its constant, get its description, and display the tag's hexadecimal value. This showcases multiple features of the EMV Parser library. ```csharp var emvData = "9F2608AABBCCDDEE12345695050000000000"; var data = Convert.FromHexString(emvData); var tagsList = EMVTLVParser.ParseTagsList(data); // Getting tag value using constant var applicationCryptogram = tagsList.GetTag(EMVTags.ApplicationCryptogram); // Getting tag description var tagDescription = EMVTags.GetTagName(applicationCryptogram.TagHex); // Output information Console.WriteLine($"Tag: {applicationCryptogram.TagHex}"); Console.WriteLine($"Description: {tagDescription}"); Console.WriteLine($"Value: {applicationCryptogram.ValueHex}"); ``` -------------------------------- ### Practical CDOL1 Processing Example Source: https://github.com/robonet/emvparser/blob/main/docs/main.en.md A practical example of parsing CDOL1 from a card response, displaying the structure and calculating the total expected data length. This informs developers on the exact data required for subsequent EMV commands like GENERATE AC. ```csharp var cdol1Hex = "9F02069F1D029F03069F1A0295055F2A029A039C019F37049F21039F7C14"; var cdol1Structure = DOLParser.ParseTagsList(cdol1Hex); Console.WriteLine("CDOL1 Structure:"); Console.WriteLine("================"); int totalLength = 0; foreach (var entry in cdol1Structure) { var tagName = EMVTags.GetTagName(entry.TagHex) ?? "Unknown Tag"; Console.WriteLine($"{entry.TagHex}: {tagName} ({entry.Length} bytes)"); totalLength += entry.Length; } Console.WriteLine($"\nTotal expected data length: {totalLength} bytes"); ``` -------------------------------- ### Install RoboNet.EMVParser via .NET CLI Source: https://github.com/robonet/emvparser/blob/main/docs/main.en.md Install the RoboNet.EMVParser NuGet package using the .NET CLI command. This makes the library's functionalities available in your project. ```bash dotnet add package RoboNet.EMVParser ``` -------------------------------- ### Quick Start: Parse EMV TLV Data and DOL in C# Source: https://github.com/robonet/emvparser/blob/main/docs/main.en.md Demonstrates basic usage of RoboNet.EMVParser for parsing EMV TLV data and DOL structures. It shows how to extract all tags from EMV data and parse tag-length pairs from a DOL string. ```csharp // Example EMV data var emvData = "9F2608AABBCCDDEE12345695050000000000"; var data = Convert.FromHexString(emvData); // Get all tags IReadOnlyList tagsList = EMVTLVParser.ParseTagsList(data); // Find specific tag var tag = tagsList.GetTag("9F26"); if (tag != null) { Console.WriteLine($"Tag value: {tag.ValueHex}"); } // Parse DOL (Data Object List) - contains tag-length pairs without values var dolData = "9F02069F1D029F03069F1A0295055F2A029A039C019F37049F21039F7C14"; IReadOnlyList dolTags = DOLParser.ParseTagsList(dolData); foreach (var dolTag in dolTags) { Console.WriteLine($"DOL Tag: {dolTag.TagHex}, Expected Length: {dolTag.Length}"); } ``` -------------------------------- ### Git Commit for New Feature Source: https://github.com/robonet/emvparser/blob/main/RELEASE.md Example Git commit command for adding a new feature. Using the 'feat:' prefix will automatically trigger a minor version increment. ```bash git add . git commit -m "feat: added EMV Contactless specification support" git push origin main ``` -------------------------------- ### Parse DOL Structures in C# Source: https://github.com/robonet/emvparser/blob/main/README.md This example demonstrates parsing Data Object List (DOL) structures, such as CDOL1 or DDOL, which contain tag-length pairs without the actual values. The `DOLParser.ParseTagsList` method from RoboNet.EMVParser takes a string representing the DOL data and returns a list of `TagLengthPointer` objects, each detailing the tag and its expected length. This functionality requires the RoboNet.EMVParser NuGet package. ```csharp // Parse CDOL1 or DDOL structure - contains tag-length pairs without values var dolData = "9F02069F1D029F03069F1A0295055F2A029A039C019F37049F21039F7C14"; IReadOnlyList dolTags = DOLParser.ParseTagsList(dolData); foreach (var dolTag in dolTags) { Console.WriteLine($"Tag: {dolTag.TagHex}, Expected Length: {dolTag.Length}"); } ``` -------------------------------- ### Retrieve EMV Tag Values in C# Source: https://github.com/robonet/emvparser/blob/main/docs/main.en.md Provides examples of retrieving EMV tag values in various formats, including hexadecimal string, byte array, ASCII string, and numeric long. It highlights the convenience methods available for different data types. ```csharp // Get value in HEX string hexValue = tagsList.GetTagValueHex("5F2A"); // Get value as byte array Memory byteValue = tagsList.GetTagValue("5F2A"); // Get string value (for ASCII data) string stringValue = tag.ValueString; // Get numeric value long numericValue = tag.ValueNumeric; ``` -------------------------------- ### Get EMV Tag Description by Number in C# Source: https://github.com/robonet/emvparser/blob/main/docs/main.en.md Demonstrates how to retrieve the human-readable description of an EMV tag using its hexadecimal identifier. This utilizes the `EMVTags.GetTagName` method for easy access to tag information. ```csharp var tagName = EMVTags.GetTagName("5F2A"); // Returns: "Transaction Currency Code" ``` -------------------------------- ### Get Application Preferred Name in C# Source: https://github.com/robonet/emvparser/blob/main/docs/main.en.md Shows how to retrieve the Application Preferred Name (tag 9F12) from EMV data, with automatic handling of ISO-8859-X encoding based on the Issuer Code Table Index (tag 9F11). It returns the decoded name or null if the tag is not found. ```csharp // Get tag list from EMV data var data = Convert.FromHexString(emvData); var tagsList = EMVTLVParser.ParseTagsList(data); // Get application preferred name with proper encoding string? applicationName = tagsList.GetApplicationPreferredName(); // Example: "МИР Классик" or "Visa Debit" ``` -------------------------------- ### Git Commit for Bug Fix Source: https://github.com/robonet/emvparser/blob/main/RELEASE.md Example Git commit command for applying a bug fix. Following the conventional commits standard with 'fix:' prefix will automatically trigger a patch version increment. ```bash git add . git commit -m "fix: correct handling of null values in TagPointer" git push origin main ``` -------------------------------- ### Get Last Git Tag Source: https://github.com/robonet/emvparser/blob/main/RELEASE.md Command to retrieve the most recent Git tag in the repository. This is used for debugging version determination issues. ```bash git describe --tags --abbrev=0 ``` -------------------------------- ### Handle Long Tags and Lengths in EMV TLV Parsing (C#) Source: https://github.com/robonet/emvparser/blob/main/docs/main.en.md Illustrates how RoboNet.EMVParser automatically handles EMV TLV data with multi-byte tags and multi-byte lengths. It shows examples of parsing both scenarios. ```csharp // Example with long tag var longTagData = "1F818001020304"; // Tag: 1F8180, Length: 01, Value: 02 03 04 var parsedTag = EMVTLVParser.ParseTagsList(Convert.FromHexString(longTagData)); // Example with long length var longLengthData = "9F26820100" + new string('FF', 256); // 256 bytes of data var parsedLength = EMVTLVParser.ParseTagsList(Convert.FromHexString(longLengthData)); ``` -------------------------------- ### Git Commit for Breaking Change Source: https://github.com/robonet/emvparser/blob/main/RELEASE.md Example Git commit command for a breaking change. Using 'feat!:' or 'fix!:' with a 'BREAKING CHANGE:' description in the commit body will automatically trigger a major version increment. ```bash git add . git commit -m "feat!: new asynchronous API The old synchronous API is marked as Obsolete. BREAKING CHANGE: TLVParser.Parse method replaced with TLVParser.ParseAsync. Use await TLVParser.ParseAsync() instead of TLVParser.Parse()." git push origin main ``` -------------------------------- ### Skip CI Build in Git Commit Source: https://github.com/robonet/emvparser/blob/main/RELEASE.md Example of how to include '[skip ci]' in a Git commit message to prevent the CI workflow from triggering a release. This is useful for commits that do not require a version update. ```bash git commit -m "docs: documentation update [skip ci]" ``` -------------------------------- ### Access Tag Values in Various Formats in C# Source: https://github.com/robonet/emvparser/blob/main/README.md This snippet illustrates how to access and retrieve tag values from a parsed EMV TLV list in different formats using extension methods provided by RoboNet.EMVParser. It shows how to find a tag by its hex string, and then get its value as a hex string, a Memory span, a string, or a numeric value. This requires the RoboNet.EMVParser NuGet package and a previously parsed `tagsList`. ```csharp // Search in tag list var tag = tagsList.GetTag("5F2A"); // Get value in different formats string hexValue = tagsList.GetTagValueHex("5F2A"); Memory byteValue = tagsList.GetTagValue("5F2A"); string stringValue = tag.ValueString; long numericValue = tag.ValueNumeric; ``` -------------------------------- ### Basic DOL Parsing and Display Source: https://github.com/robonet/emvparser/blob/main/docs/main.en.md Demonstrates how to parse a CDOL1 string into a list of TagLengthPointer objects and display their properties, including tag name, expected length, and data type. Requires the EMVTags class for tag name resolution. ```csharp var cdol1Data = "9F02069F1D029F03069F1A0295055F2A029A039C019F37049F21039F7C14"; IReadOnlyList dolTags = DOLParser.ParseTagsList(cdol1Data); foreach (var dolTag in dolTags) { string tagName = EMVTags.GetTagName(dolTag.TagHex) ?? "Unknown"; Console.WriteLine($"Tag: {dolTag.TagHex} ({tagName})"); Console.WriteLine($"Expected Length: {dolTag.Length} bytes"); Console.WriteLine($"Data Type: {dolTag.TagDataType}"); Console.WriteLine("---"); } ``` -------------------------------- ### DOL Parsing from Different Input Types Source: https://github.com/robonet/emvparser/blob/main/docs/main.en.md Shows the flexibility of `DOLParser.ParseTagsList` by demonstrating how it can accept input not only as a hex string but also as a byte array or a Memory span, facilitating integration with various data sources. ```csharp // From hex string var dolTags1 = DOLParser.ParseTagsList("9F02069F1D02"); // From byte array byte[] dolBytes = Convert.FromHexString("9F02069F1D02"); var dolTags2 = DOLParser.ParseTagsList(dolBytes); // From Memory Memory dolMemory = dolBytes.AsMemory(); var dolTags3 = DOLParser.ParseTagsList(dolMemory); ``` -------------------------------- ### High-Performance Span-Based EMV Operations in C# Source: https://context7.com/robonet/emvparser/llms.txt Illustrates how to use `ReadOnlySpan` and `Memory` for efficient, zero-copy EMV data parsing with the RoboNet.EMVParser library. This approach minimizes memory allocations and GC pressure, ideal for high-throughput applications. ```csharp using RoboNet.EMVParser; using System.Diagnostics; // Span-based parsing for zero-copy operations byte[] emvDataBytes = Convert.FromHexString( "5F2A02097882021C009F26080123456789ABCDEF9F2701809F3303E0F0C8" ); // Use ReadOnlySpan for reading without allocations ReadOnlySpan dataSpan = emvDataBytes.AsSpan(); // Extract tag value directly using Span (no memory allocation) Span tagValue = TLVParser.GetTagValue(dataSpan, "9F26"); Console.WriteLine($"Cryptogram: {Convert.ToHexString(tagValue)}"); // Performance comparison var stopwatch = Stopwatch.StartNew(); for (int i = 0; i < 10000; i++) { // Span-based: minimal allocations var value = TLVParser.GetTagValue(dataSpan, "9F26"); } stopwatch.Stop(); Console.WriteLine($"Span-based: {stopwatch.ElapsedMilliseconds}ms"); // Memory for scenarios requiring ownership stopwatch.Restart(); Memory dataMemory = emvDataBytes.AsMemory(); for (int i = 0; i < 10000; i++) { var value = TLVParser.GetTagValue(dataMemory, "9F26"); } stopwatch.Stop(); Console.WriteLine($"Memory-based: {stopwatch.ElapsedMilliseconds}ms"); // Parsing with ReadOnlyMemory returns readonly structures string hexData = "5F2A02097882021C009F26080123456789ABCDEF"; IReadOnlyList readonlyTags = TLVParser.ParseTagsList(hexData); foreach (var tag in readonlyTags) { // TagPointerReadonly provides immutable view Console.WriteLine($"{tag.TagHex}: {tag.ValueHex}"); } // Benefits: // 1. No heap allocations for temporary data // 2. Better cache locality // 3. Reduced GC pressure // 4. Suitable for high-frequency parsing // 5. Stack allocation where possible ``` -------------------------------- ### Robust DOL Parsing with Error Handling Source: https://github.com/robonet/emvparser/blob/main/docs/main.en.md Illustrates how to implement robust error handling when parsing DOL data using a try-catch block. This ensures that the application can gracefully manage exceptions that might occur due to malformed or invalid DOL structures. ```csharp try { var dolTags = DOLParser.ParseTagsList(dolData); // Process DOL structure } catch (Exception ex) { Console.WriteLine($"DOL parsing failed: {ex.Message}"); } ``` -------------------------------- ### TagLengthPointer Properties Access Source: https://github.com/robonet/emvparser/blob/main/docs/main.en.md Illustrates how to access various properties of a TagLengthPointer object after parsing a DOL. This includes raw byte data, length, hex representations, human-readable names, and metadata like data type and class type. ```csharp var dolTag = dolTags.First(); Memory tlData = dolTag.TL; Memory tagBytes = dolTag.Tag; int expectedLength = dolTag.Length; string tlHex = dolTag.TLHex; string tagHex = dolTag.TagHex; string? tagName = dolTag.Name; DataType dataType = dolTag.TagDataType; ClassType classType = dolTag.TagClassType; ``` -------------------------------- ### Use EMVTags Constants in C# Source: https://github.com/robonet/emvparser/blob/main/docs/main.en.md Illustrates the benefit of using predefined constants from the `EMVTags` class instead of string literals for EMV tag identifiers. This enhances type safety and code maintainability. ```csharp // Using constant instead of string literal var tag = tagsList.GetTag(EMVTags.TransactionCurrencyCode); // instead of "5F2A" if (tag != null) { Console.WriteLine($"Currency tag value: {tag.ValueHex}"); } ``` -------------------------------- ### Parse and Navigate Constructed (Nested) EMV Tags in C# Source: https://context7.com/robonet/emvparser/llms.txt Demonstrates how to parse TLV-encoded EMV data, access constructed tags, and navigate their nested internal tag structures using the RoboNet.EMVParser library. This is useful for handling hierarchical EMV data like FCI templates. ```csharp using RoboNet.EMVParser; // Example with FCI (File Control Information) template - tag 6F contains nested tags var fciData = "6F1A840E325041592E5359532E4444463031A508880102500A4D61737465726361726432"; // Tag 6F (FCI Template) contains: // Tag 84 (DF Name): 325041592E5359532E4444463031 // Tag A5 (FCI Proprietary Template) contains: // Tag 88: 02 // Tag 50: 4D61737465726361726432 var data = Convert.FromHexString(fciData); var tagsList = TLVParser.ParseTagsList(data); // The root level contains tag 6F Console.WriteLine($"Root tags: {tagsList.Count}"); // Access the constructed tag var fciTemplate = tagsList.GetTag("6F"); if (fciTemplate != null) { Console.WriteLine($"Tag {fciTemplate.TagHex} is constructed: {fciTemplate.TagDataType == DataType.ConstructedDataObject}"); Console.WriteLine($"Contains {fciTemplate.InternalTags.Count} internal tags"); // Navigate internal tags foreach (var internalTag in fciTemplate.InternalTags) { Console.WriteLine($" Internal Tag: {internalTag.TagHex} ({internalTag.Name})"); Console.WriteLine($" Value: {internalTag.ValueHex}"); // Recursively handle nested constructed tags if (internalTag.InternalTags.Count > 0) { Console.WriteLine($" Contains {internalTag.InternalTags.Count} nested tags:"); foreach (var nestedTag in internalTag.InternalTags) { Console.WriteLine($" - {nestedTag.TagHex}: {nestedTag.ValueHex} ({nestedTag.Name})"); } } } } // Search within constructed tags (automatically searches nested structures) var dfName = tagsList.GetTag("84"); // Will find 84 even though it's nested inside 6F if (dfName != null) { Console.WriteLine($"\nFound nested tag 84: {dfName.ValueString}"); } // GetTag automatically traverses the entire tree structure var sfi = tagsList.GetTag("88"); // Finds 88 nested inside A5 inside 6F Console.WriteLine($"Found deeply nested tag 88: {sfi?.ValueHex}"); ``` -------------------------------- ### Find Specific EMV Tag in C# Source: https://github.com/robonet/emvparser/blob/main/docs/main.en.md Demonstrates how to search for a specific EMV tag, identified by its hexadecimal string, within a list of tags or directly within raw EMV data. It shows how to retrieve the tag object or its value if found. ```csharp // Search in tag list var tag = tagsList.GetTag("5F2A"); if (tag != null) { Console.WriteLine($"Found tag value: {tag.ValueHex}"); } // Direct search in data var tagValue = EMVTLVParser.GetTagValue(data, "5F2A"); Console.WriteLine($"Tag value: {Convert.ToHexString(tagValue.Span)}"); ``` -------------------------------- ### Parse All TLV Tags from EMV Data in C# Source: https://github.com/robonet/emvparser/blob/main/docs/main.en.md Demonstrates how to parse a complete EMV TLV byte array and iterate through all extracted tags. It shows how to access the hexadecimal representation of tags and their values. ```csharp var data = Convert.FromHexString(emvData); IReadOnlyList tagsList = EMVTLVParser.ParseTagsList(data); foreach (var tag in tagsList) { Console.WriteLine($"Tag: {tag.TagHex}, Value: {tag.ValueHex}"); } ``` -------------------------------- ### Search and Extract EMV Tag Values Source: https://context7.com/robonet/emvparser/llms.txt Demonstrates how to search for and extract tag values from a parsed tag list, supporting nested constructed tags. It uses extension methods for convenient access to tag data as hex, numeric, or byte arrays. Handles cases where tags might be missing. ```csharp using RoboNet.EMVParser; var emvData = "5F2A02097882021C00950580800088009F26080123456789ABCDEF9F2701809F37040F00BA20"; var data = Convert.FromHexString(emvData); var tagsList = TLVParser.ParseTagsList(data); // Find specific tag in the list TagPointer? currencyTag = tagsList.GetTag("5F2A"); if (currencyTag != null) { Console.WriteLine($"Found tag: {currencyTag.TagHex}"); Console.WriteLine($"Tag name: {currencyTag.Name}"); Console.WriteLine($"Value as hex: {currencyTag.ValueHex}"); Console.WriteLine($"Value as numeric: {currencyTag.ValueNumeric}"); Console.WriteLine($"Full TLV: {currencyTag.TLVHex}"); } // Get tag value directly as byte array Memory cryptogramBytes = tagsList.GetTagValue("9F26"); Console.WriteLine($"Cryptogram bytes: {Convert.ToHexString(cryptogramBytes.Span)}"); // Get tag value as hex string string cryptogramHex = tagsList.GetTagValueHex("9F26"); Console.WriteLine($"Cryptogram hex: {cryptogramHex}"); // Get complete TLV data (tag + length + value) Memory completeTlv = tagsList.GetTagData("9F37"); string completeTlvHex = tagsList.GetTagDataHex("9F37"); Console.WriteLine($"Complete TLV: {completeTlvHex}"); // Returns null or empty for missing tags var missingTag = tagsList.GetTag("9999"); Console.WriteLine($"Missing tag: {missingTag == null}"); // Output: True ``` -------------------------------- ### Parse EMV Data with Multi-Byte Tags and Lengths in C# Source: https://context7.com/robonet/emvparser/llms.txt Demonstrates how to use the TLVParser to process EMV data containing multi-byte tag identifiers and variable-length encoding schemes. The library automatically handles complex tag formats (like the 0x1F continuation indicator) and long-form lengths (where the first length byte indicates more bytes follow), ensuring correct parsing of tag values and their lengths. ```csharp using RoboNet.EMVParser; // Example with multi-byte tag (tag 9F40 has 2 bytes) var multiByteTagData = "9F400580000000009F3704ABCDEF12"; var data1 = Convert.FromHexString(multiByteTagData); var tags1 = TLVParser.ParseTagsList(data1); foreach (var tag in tags1) { Console.WriteLine($"Tag: {tag.TagHex} ({tag.Tag.Length} bytes)"); Console.WriteLine($"Value: {tag.ValueHex}"); Console.WriteLine($"Length: {tag.Length}"); } // Example with long form tag (first byte = 0x1F indicates continuation) var longFormTag = "1F818001AABBCC"; // Tag: 1F8180, Length: 01, Value: AABBCC var data2 = Convert.FromHexString(longFormTag); var tags2 = TLVParser.ParseTagsList(data2); var longTag = tags2[0]; Console.WriteLine($"Long form tag: {longTag.TagHex}"); // Output: 1F8180 Console.WriteLine($"Tag bytes: {longTag.Tag.Length}"); // Output: 3 // Example with multi-byte length (length > 127 bytes) var longLengthData = "9F26820100" + new string('A', 512); // 256 bytes of 'AA' var data3 = Convert.FromHexString(longLengthData); var tags3 = TLVParser.ParseTagsList(data3); var longLengthTag = tags3[0]; Console.WriteLine($"Tag: {longLengthTag.TagHex}"); Console.WriteLine($"Value length: {longLengthTag.Length} bytes"); // Output: 256 Console.WriteLine($"First 10 bytes: {longLengthTag.ValueHex.Substring(0, 20)}"); // The library automatically handles: // - Tags where first 5 bits = 11111 (continuation indicator) // - Length first bit = 1 (multi-byte length indicator) // - Proper byte boundary detection and parsing ``` -------------------------------- ### Parse EMV Data Object List (DOL) Structures Source: https://context7.com/robonet/emvparser/llms.txt This snippet shows how to parse Data Object List (DOL) structures, such as CDOL1, CDOL2, and DDOL. These structures define the required data format for EMV commands without containing the actual values. The parser returns a list of tag-length pairs. ```csharp using RoboNet.EMVParser; // CDOL1 (Card Risk Management Data Object List 1) from tag 8C // This defines what data the card expects in GENERATE AC command var cdol1Data = "9F02069F1D029F03069F1A0295055F2A029A039C019F37049F21039F7C14"; IReadOnlyList cdol1Tags = DOLParser.ParseTagsList(cdol1Data); Console.WriteLine("CDOL1 Structure (Tag-Length pairs):"); Console.WriteLine("===================================="); int totalLength = 0; foreach (var dolTag in cdol1Tags) { string tagName = dolTag.Name ?? "Unknown"; Console.WriteLine($"Tag: {dolTag.TagHex}"); Console.WriteLine($" Name: {tagName}"); Console.WriteLine($" Expected Length: {dolTag.Length} bytes"); Console.WriteLine($" Data Type: {dolTag.TagDataType}"); Console.WriteLine($" TL (hex): {dolTag.TLHex}"); totalLength += dolTag.Length; } Console.WriteLine($"\nTotal data length required: {totalLength} bytes"); // Parse from different input types byte[] dolBytes = Convert.FromHexString(cdol1Data); var fromBytes = DOLParser.ParseTagsList(dolBytes); Memory dolMemory = dolBytes.AsMemory(); var fromMemory = DOLParser.ParseTagsList(dolMemory); // Example output interpretation: // 9F02 (Amount, Authorized): 6 bytes - transaction amount in cents // 9F1D (Terminal Risk Management Data): 2 bytes - terminal capabilities // 5F2A (Transaction Currency Code): 2 bytes - ISO currency code // This tells you what data to collect and send to the card ``` -------------------------------- ### Decode EMV Application Preferred Name with Encoding in C# Source: https://context7.com/robonet/emvparser/llms.txt Illustrates how to retrieve and decode the Application Preferred Name (tag 9F12) from EMV data, respecting the character encoding specified by the Issuer Code Table (tag 9F11). The utility automatically selects the correct encoding (e.g., ISO-8859-1, ISO-8859-5) based on the code table value and falls back to ASCII if no code table is present. It also handles cases where the tag might be missing. ```csharp using RoboNet.EMVParser; // EMV data containing Application Preferred Name (9F12) and Issuer Code Table (9F11) var emvData = "9F12104D494220D0BAD0BBD0B0D181D181D0B8D0BA9F110105"; // 9F12: МИР Классик (in ISO-8859-5 Cyrillic encoding) // 9F11: 05 (indicates ISO-8859-5 character set) var data = Convert.FromHexString(emvData); var tagsList = TLVParser.ParseTagsList(data); // Get properly decoded application name string? applicationName = tagsList.GetApplicationPreferredName(); Console.WriteLine($"Application Name: {applicationName}"); // Output: МИР Классик // Manual extraction showing what the utility does internally var appNameTag = tagsList.GetTag("9F12"); var codeTableTag = tagsList.GetTag("9F11"); if (appNameTag != null) { if (codeTableTag != null) { int codeTableIndex = (int)codeTableTag.ValueNumeric; Console.WriteLine($"Code Table Index: {codeTableIndex}"); // Output: 5 (ISO-8859-5) // The utility automatically selects correct encoding: // 01 = ISO-8859-1 (Latin-1) // 02 = ISO-8859-2 (Latin-2) // 05 = ISO-8859-5 (Cyrillic) // And so on... } else { // Falls back to ASCII if no code table specified Console.WriteLine($"Name (ASCII): {appNameTag.ValueString}"); } } // Example with Latin characters (no special encoding needed) var visaData = "9F120A56697361204465626974"; // "Visa Debit" in ASCII var visaTags = TLVParser.ParseTagsList(Convert.FromHexString(visaData)); string? visaName = visaTags.GetApplicationPreferredName(); Console.WriteLine($"Visa Application: {visaName}"); // Output: Visa Debit // Handles missing tags gracefully var emptyData = "9F2608ABCDEF12345678"; var emptyTags = TLVParser.ParseTagsList(Convert.FromHexString(emptyData)); string? missingName = emptyTags.GetApplicationPreferredName(); Console.WriteLine($"Missing name is null: {missingName == null}"); // Output: True ``` -------------------------------- ### Parse Complete TLV Data Structure in C# Source: https://context7.com/robonet/emvparser/llms.txt Parses a complete EMV TLV data structure into a list of TagPointer objects. It automatically detects and handles nested constructed tags. The output provides tag details like name, value, length, data type, and class type. Dependencies: RoboNet.EMVParser library. ```csharp using RoboNet.EMVParser; // Sample EMV data from a payment transaction var emvData = "5F2A02097882021C00950580800088009A032110149C01009F02060000000020219F03060000000000009F0902008C9F100706010A03A480109F1A0202769F26080123456789ABCDEF9F2701809F3303E0F0C89F34034103029F3501229F3602003E9F37040F00BA209F41030010518407A0000000031010"; var data = Convert.FromHexString(emvData); // Parse all tags into a list IReadOnlyList tagsList = TLVParser.ParseTagsList(data); // Iterate through all tags foreach (var tag in tagsList) { string tagName = tag.Name ?? "Unknown"; Console.WriteLine($"Tag: {tag.TagHex} ({tagName})"); Console.WriteLine($" Value (Hex): {tag.ValueHex}"); Console.WriteLine($" Value (ASCII): {tag.ValueString}"); Console.WriteLine($" Length: {tag.Length} bytes"); Console.WriteLine($" Data Type: {tag.TagDataType}"); Console.WriteLine($" Class Type: {tag.TagClassType}"); // Handle constructed tags with nested data if (tag.InternalTags.Count > 0) { Console.WriteLine($" Internal Tags: {tag.InternalTags.Count}"); foreach (var internalTag in tag.InternalTags) { Console.WriteLine($" - {internalTag.TagHex}: {internalTag.ValueHex}"); } } } ``` -------------------------------- ### Parse All Tags from EMV Data in C# Source: https://github.com/robonet/emvparser/blob/main/README.md This snippet demonstrates how to extract all TLV (Tag-Length-Value) tags from raw EMV data using the RoboNet.EMVParser library. It takes a byte array representing the EMV data and returns a read-only list of TagPointer objects, each containing tag and value information. Dependencies include the RoboNet.EMVParser NuGet package. ```csharp var someEMVData = "5F2A02097882021C00950580800088009A032110149C01009F02060000000020219F03060000000000009F0902008C9F100706010A03A480109F1A0202769F26080123456789ABCDEF9F2701809F3303E0F0C89F34034103029F3501229F3602003E9F37040F00BA209F41030010518407A0000000031010"; var data = Convert.FromHexString(someEMVData); // Get all tags IReadOnlyList tagsList = TLVParser.ParseTagsList(data); foreach (var tag in tagsList) { Console.WriteLine($"Tag: {tag.TagHex}, Value: {tag.ValueHex}"); } ``` -------------------------------- ### Delete Git Tag and Push Source: https://github.com/robonet/emvparser/blob/main/RELEASE.md Commands to delete a Git tag locally and from the remote repository (GitHub). This is part of the version rollback process. ```bash git tag -d v0.9.0 git push origin :refs/tags/v0.9.0 ``` -------------------------------- ### Read Specific Tag Value from EMV Data in C# Source: https://github.com/robonet/emvparser/blob/main/README.md This code snippet shows how to retrieve the value of a specific EMV tag from a byte array containing EMV data. It uses the `ReadTagValue` method from the RoboNet.EMVParser library, specifying the data span and the target tag's hexadecimal string representation. The output is the tag's value as a hexadecimal string. Requires the RoboNet.EMVParser NuGet package. ```csharp // Get value of tag 5F2A Span tagValue = TLVParser.ReadTagValue(data.AsSpan(), "5F2A"); Console.WriteLine("Tag 5F2A value: " + Convert.ToHexString(tagValue)); ``` -------------------------------- ### Extract Specific Tag Value in C# Source: https://context7.com/robonet/emvparser/llms.txt Extracts the value of a specific EMV tag directly from raw TLV data without parsing the entire structure. Supports Span, Memory, and byte arrays for input. Returns an empty Span if the tag is not found. Dependencies: RoboNet.EMVParser library. ```csharp using RoboNet.EMVParser; var emvData = "5F2A02097882021C00950580800088009F26080123456789ABCDEF9F2701809F3303E0F0C8"; var data = Convert.FromHexString(emvData); // Get value of Transaction Currency Code (tag 5F2A) Span currencyCodeBytes = TLVParser.GetTagValue(data.AsSpan(), "5F2A"); Console.WriteLine($"Currency Code: {Convert.ToHexString(currencyCodeBytes)}"); // Output: 0978 // Get value in hex format directly string applicationCryptogram = TLVParser.GetHexTagValue(data, "9F26"); Console.WriteLine($"Cryptogram: {applicationCryptogram}"); // Output: 0123456789ABCDEF // Works with Memory for memory management Memory cryptogramValue = TLVParser.GetTagValue(data.AsMemory(), "9F26"); Console.WriteLine($"Cryptogram length: {cryptogramValue.Length} bytes"); // Returns empty if tag not found var missingTag = TLVParser.GetTagValue(data.AsSpan(), "9999"); Console.WriteLine($"Missing tag is empty: {missingTag.IsEmpty}"); // Output: True ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.