Example #1
0
        // 根据当前的所有元素,设置 Content parameter 元素内容
        // parameters:
        //      trim_right  是否要截掉右侧多余的连续 0?截掉是一般做法。而不截掉,也就是保留足够 byte 数,足以应对以后元素增多以后的局面,保证 content parameter 本身耗用的空间和以前一致,有利于芯片以后修改内容时的布局。
        public void SetContentParameter(bool trim_right)
        {
            var content_parameter = this.FindElement(ElementOID.ContentParameter);
            if (content_parameter == null)
                content_parameter = this.NewElement(ElementOID.ContentParameter, null);

            UInt64 value = 0;
            foreach (Element element in this._elements)
            {
                int oid = (int)element.OID;
                if (oid >= 3)
                {
                    // TODO: 测试 0x80000000 >> 0 会不会有问题
                    value |= 0x8000000000000000 >> (oid - 3);
                }
            }

            if (value == 0)
            {
                this.RemoveElement(ElementOID.ContentParameter);
                return;
            }

            var bytes = Compact.ReverseBytes(BitConverter.GetBytes(value));
            if (trim_right)
                bytes = Compact.TrimRight(bytes);
            content_parameter.Content = bytes;
            content_parameter.Text = Element.GetHexString(content_parameter.Content);
        }
Example #2
0
        // 解析 Long Numeric String
        // 注意 start 位置的 byte 应该是 0xfb
        // parameters:
        //      used_bytes  返回用掉的 bytes 数
        public static string DecodeLongNumericString(byte[] data,
                                                     int start,
                                                     out int used_bytes)
        {
            used_bytes = 0;
            byte lead = data[start];

            if (lead != 0xfb)
            {
                throw new ArgumentException("开始的第一个 byte 必须为 0xfb", $"{nameof(data)}, {nameof(start)}");
            }
            byte second = data[start + 1];
            // 解码后的数字应有的字符数
            int decimal_length = ((second >> 4) & 0x0f) + 9;
            // 编码后的 bytes 数
            int encoded_bytes = (second & 0x0f) + 4;

            if (encoded_bytes > 19)
            {
                throw new Exception($"Long Numeric String 的编码后 bytes 数({encoded_bytes})不合法,应小于等于 19");
            }

            string result = "";

            {
                byte[] bytes = new byte[encoded_bytes];
                Array.Copy(data, start + 2, bytes, 0, encoded_bytes);
                result = Compact.IntegerExtract(bytes);
            }

            // 补齐前方的 '0'
            result.PadLeft(decimal_length, '0');
            used_bytes = encoded_bytes + 2;
            return(result);
        }
Example #3
0
        // 编码范围在 'A'-'9' 内的三个字符为两个 bytes
        public static byte[] EncodeTriple(int c1, int c2, int c3)
        {
            List <byte> results = new List <byte>();
            uint        v       = (1600 * (uint)c1) + (40 * (uint)c2) + (uint)c3 + 1;

            if (v > UInt16.MaxValue)
            {
                throw new Exception($"{v} 溢出 16 bit 整数范围");
            }
            return(Compact.ReverseBytes(BitConverter.GetBytes((UInt16)v)));
        }
Example #4
0
        // 以 long numeric string 方式编码一个数字字符串
        // 算法可参考:
        // https://www.ipc.be/~/media/documents/public/operations/rfid/ipc%20rfid%20standard%20for%20test%20letters.pdf?la=en
        public static byte[] EncodeLongNumericString(string text)
        {
            if (text.Length < 9)
            {
                throw new ArgumentException($"用于编码的数字字符串不应短于 9 字符(但现在是 {text.Length} 字符)");
            }

            byte[] bytes = Compact.IntegerCompact(text);
            if (bytes.Length < 4)
            {
                throw new ArgumentException($"数字字符串编码后不应短于 4 bytes(但现在是 {bytes.Length} bytes)");
            }

            byte second = (byte)((((text.Length - 9) << 4) & (byte)0xf0) | ((bytes.Length - 4) & 0x0f));

            List <byte> results = new List <byte>();

            results.Add(0xfb);
            results.Add(second);
            results.AddRange(bytes);

            return(results.ToArray());
        }