Generate Han Xin Code Barcodes in C#

Overview

Han Xin Code, alternatively referred to as Chinese Sensible, is a matrix symbology introduced in 2007. It was developed to encode both simplified Chinese characters and all ASCII characters and digits. Han Xin Code symbols are two-dimensional and have a variable-size matrix structure. They comprise an arrangement of black and white modules arranged in a square pattern. The ownership and governance of this barcode standard are held by GS1 China.

With the minimum error correction level settings, Han Xin Code can encode up to 2,174 common Chinese characters, 3,261 binary bytes, 4,350 ASCII characters, or 7,827 digits. Multiple data types can be encoded in a single barcode. This standard is defined the in AIMD-015 barcode symbology specification - Han Xin Code.

Version Settings

Han Xin Code provides 84 variants of different sizes denoted as Version 1, Version 2 … Version 84. Version 1 has 23 modules × 23 modules; Version 2 contains 25 modules × 25 modules, and so on, increasing by modules per side up to Version 84, which has 189 modules × 189 modules.

By default, the HanXinVersion property of class HanXinParameters is set to HanXinVersion.Auto. In this mode, the encoder automatically picks the smallest possible version. To set a specific version, HanXinVersion needs to be initizalized with the corresponding value: from HanXinVersion.Version01 to HanXinVersion.Version84.

Version 1 Version 24 Version 84

The following code sample explains how to set the Han Xin Code version.

using (var bg = new BarcodeGenerator(EncodeTypes.HanXin, "1234567890"))
{
    // Auto (by default)
    var img = bg.GenerateBarCodeImage();
    img.Save(Global.PathCombine({path}, "ver_auto.png"));

    // Version 24
    bg.Parameters.Barcode.HanXin.HanXinVersion = HanXinVersion.Version24;
    img = bg.GenerateBarCodeImage();
    img.Save(Global.PathCombine({path}, "ver24.png"));
}

Encoding Mode Settings

The barcode library supports different encoding modes to generate Han Xin barcodes. The required mode can be selected by setting the HanXinEncodeMode property of class HanXinParameters. The possible values are defined in the HanXinEncodeMode enumeration. These modes are briefly described below:

  • Auto. This mode enables a sequence of Numeric, Text, Binary and 4 GB18030 (Chinese) modes changing automatically. Numeric, Text, and 4 GB18030 modes are internal modes, so users cannot select them explicitly. It is set by default, but it may be not suitable for some Unicode characters.
  • Binary. The Binary mode encodes binary data in any form and encodes them in their binary byte. Every byte in Binary mode is represented by 8 bits.
  • ECI. The Extended Channel Interpretation (ECI) mode indicates the encoded data is interpreted according to the ECI protocol defined by the AIM ECI Specifications.
  • Unicode. The Unicode mode designs a way to represent any text data reference to UTF8 encoding/charset in Han Xin Code.
  • URI. The URI mode indicates the data represented in Han Xin Code is Uniform Resource Identifier (URI) reference to RFC 3986.
  • Extended. Extended mode allows setting more flexible combinations of other modes. This mode is currently not supported, but its implementation is planned in future.

Auto Encoding Mode

In the Auto encoding mode, the barcode data can be encoded using Numeric, Text, Binary, and 4 GB18030 (Chinese) modes.

The following code sample shows how to generate Han Xin barcodes using the Auto mode.

// Text + Region One + Region Two + GB18030 2 Byte
var str = "abc123全ň全漄灟漄灟螅全ň螅螅螅";

using (var bg = new BarcodeGenerator(EncodeTypes.HanXin, str))
{
    bg.Parameters.Barcode.HanXin.HanXinEncodeMode = HanXinEncodeMode.Auto; // It is already Auto by default
    var img = bg.GenerateBarCodeImage();
}

Binary Encoding Mode

The Bytes mode serves to encode byte streams. The code sample below explains how to work with this encoding mode.

// Binary mode 
var str = "IJK";

using (var bg = new BarcodeGenerator(EncodeTypes.HanXin, str))
{
    bg.Parameters.Barcode.HanXin.HanXinEncodeMode = HanXinEncodeMode.Binary;
    var img = bg.GenerateBarCodeImage();

    using (var r = new BarCodeReader(img, DecodeType.HanXin))
    {
        var found = r.ReadBarCodes();
        Assert.AreEqual(1, found.Length);
        var binary = "494a4b";
        Assert.AreEqual(binary.ToLower(), found[0].CodeText.ToLower());
    }
}

ECI Mode

The Extended Channel Interpretation (ECI) mode indicates that the encoded data is interpreted according to the ECI protocol defined by the AIM ECI Specifications. The data sequence is encoded according to the rules of other modes. The HanXinECIEncoding property of class HanXinParameters needs to be initialized according to charset / ECI assignment value. By default, this property is set to ECIEncodings.ISO_8859_1 (ISO/IEC 8859-1 Latin alphabet No. 1 encoding. ECI Id:"\000003”).

The following code sample demonstrates how to use the ECI mode.

// ECI mode, Latin/Greek alphabet encoding. ECI Id:"\000009"
var str = "ΑΒΓΔΕ";

using (var bg = new BarcodeGenerator(EncodeTypes.HanXin, str))
{
    bg.Parameters.Barcode.HanXin.HanXinEncodeMode = HanXinEncodeMode.ECI;
    bg.Parameters.Barcode.HanXin.HanXinECIEncoding = ECIEncodings.ISO_8859_7;
    var img = bg.GenerateBarCodeImage();
}

Unicode Mode

The Unicode mode provides a way to store text data entered in the UTF8 encoding format within Han Xin barcodes.

The following code sample shows how to enable the Unicode mode.

var str = "abcd АБВ ıntəˈnæʃənəl 语言语言 แผ่นดินฮั่นเสื่ ∑ f(i) = ∏ 🖨 🚘✉🥇⚽ 你好測試測試 こんにちは テスト テスト 안녕하세요 테스트 테스트";

using (var bg = new BarcodeGenerator(EncodeTypes.HanXin, str))
{
    bg.Parameters.Barcode.HanXin.HanXinEncodeMode = HanXinEncodeMode.Unicode;
    var img = bg.GenerateBarCodeImage();
}

URI Mode

The URI mode indicates the data represented in Han Xin Code is Uniform Resource Identifier (URI) reference to RFC 3986.

// URI mode 
var str = "https://www.test.com/%BC%DE%ab/search=test";

using (var bg = new BarcodeGenerator(EncodeTypes.HanXin, str))
{
    bg.Parameters.Barcode.HanXin.HanXinEncodeMode = HanXinEncodeMode.URI;
    var img = bg.GenerateBarCodeImage();

    using (var r = new BarCodeReader(img, DecodeType.HanXin))
    {
        var found = r.ReadBarCodes();
        Assert.AreEqual(1, found.Length);
        Assert.AreEqual(str.ToLower(), found[0].CodeText.ToLower());
    }
}

Extended Mode

The Extended mode allows combining all supported encoding formats within a single barcode, including the following: Auto, Binary, Text, Numeric, URI, Unicode, ECI, Common Chinese Region One, Common Chinese Region Two, GB18030 Two Byte, and GB18030 Four Byte.

The barcode text can be defined manually with prefixes and doubled backslashes, e.g.: @"\auto:abc\000009:ΑΒΓΔΕ\auto:ab\\c" or using the HanXinExtCodetextBuilder.

If the barcode text contains an ECI fragment, then only the following modes can be used after the ECI fragment: Auto, Binary, Text, Numeric, URI, or ECI.

Following code examples illustrate how to use all the modes.

// Extended mode example 1
var str = @"\auto:abc\000009:ΑΒΓΔΕ\auto:abc";

var expectedStr = str.Replace(@"\auto:", "");
expectedStr = expectedStr.Replace(@"\000009:", "");

// expectedStr == "abcΑΒΓΔΕabc"

using (var bg = new BarcodeGenerator(EncodeTypes.HanXin, str))
{
    bg.Parameters.Barcode.HanXin.HanXinEncodeMode = HanXinEncodeMode.Extended;
    var img = bg.GenerateBarCodeImage();

    using (var r = new BarCodeReader(img, DecodeType.HanXin))
    {
        var found = r.ReadBarCodes();
        Assert.AreEqual(1, found.Length);
        Assert.AreEqual(expectedStr, found[0].CodeText);
    }
}

// Extended mode example 2
var str = @"\gb180302b:漄\gb180304b:㐁\region1:全\region2:螅\numeric:123\text:qwe\unicode:ıntəˈnæʃənəl" +
     @"\000009:ΑΒΓΔΕ\auto:abc\binary:abc\uri:backslashes_should_be_doubled\\000555:test";

var expectedStr = @"漄㐁全螅123qweıntəˈnæʃənəlΑΒΓΔΕabcabcbackslashes_should_be_doubled\000555:test";

using (var bg = new BarcodeGenerator(EncodeTypes.HanXin, str))
{
    bg.Parameters.Barcode.HanXin.HanXinEncodeMode = HanXinEncodeMode.Extended;
    var img = bg.GenerateBarCodeImage();

    using (var r = new BarCodeReader(img, DecodeType.HanXin))
    {
        var found = r.ReadBarCodes();
        Assert.AreEqual(1, found.Length);
        Assert.AreEqual(expectedStr, found[0].CodeText);
    }
}

// Extended mode example 3
// Using HanXinExtCodetextBuilder for Extended mode (same codetext as in previous example)
// Create codetext
var codeTextBuilder = new HanXinExtCodetextBuilder();
codeTextBuilder.AddGB18030TwoByte("漄");
codeTextBuilder.AddGB18030FourByte("㐁");
codeTextBuilder.AddCommonChineseRegionOne("全");
codeTextBuilder.AddCommonChineseRegionTwo("螅");
codeTextBuilder.AddNumeric("123");
codeTextBuilder.AddText("qwe");
codeTextBuilder.AddUnicode("ıntəˈnæʃənəl");
codeTextBuilder.AddECI("ΑΒΓΔΕ", 9);
codeTextBuilder.AddAuto("abc");
codeTextBuilder.AddBinary("abc");
codeTextBuilder.AddURI(@"backslashes_should_be_doubled\000555:test");

var expectedStr = @"漄㐁全螅123qweıntəˈnæʃənəlΑΒΓΔΕabcabcbackslashes_should_be_doubled\000555:test";

// Generate codetext
var str = codeTextBuilder.GetExtendedCodetext();

// Generate
using (var bg = new BarcodeGenerator(EncodeTypes.HanXin, str))
{
    bg.Parameters.Barcode.HanXin.HanXinEncodeMode = HanXinEncodeMode.Extended;
    var img = bg.GenerateBarCodeImage();

    using (var r = new BarCodeReader(img, DecodeType.HanXin))
    {
        var found = r.ReadBarCodes();
        Assert.AreEqual(1, found.Length);
        Assert.AreEqual(expectedStr, found[0].CodeText);
    }
}

Error Correction Settings

Han Xin Code supports the four levels of Reed-Solomon error correction as explained in the table below.

Error Correction Level Data Recovery Capability
L1 8%
L2 15%
L3 23%
L4 30%

The required error correction level can be defined using the HanXinErrorLevel property of class HanXinParameters. By default, it is set to the HanXinErrorLevel.L1 value.

The following code sample explains how to set the error correction level.

using (var bg = new BarcodeGenerator(EncodeTypes.HanXin, "1234567890"))
{
    // L4
    bg.Parameters.Barcode.HanXin.HanXinErrorLevel = HanXinErrorLevel.L4;
    var img = bg.GenerateBarCodeImage();
    img.Save(Global.PathCombine({path}, "img.png"));
}