java实现PBOC的TL分V分彩网站开发格式解析,超简单的解析

简介下TLV:分V分彩网站开发haozbbs.comQ1446595067

PBOC基本信息数据采用TLV(tag-length-value)的表示方式,即每项由tag标签(T),长度(L)和取值(V)构成。

  tag标签的属性为bit,由16进制表示,占1~2个字节长度。若tag标签的第一个字节(注:字节排序方向为从左往右数(b8~b0),第一个字节即为最左边的字节。bit排序规则同理。)的后四个bit为“1111”,则说明该tag占两个字节,例如“9F33”;否则占一个字节,例如“95”。b8和b7两位标识tag所属类别. 这个可以暂时不用理. b6决定当前的TLV数据是一个单一的数据和复合结构的数据. 复合的TLV是指value域里也包含一个或多个TLV, 类似嵌套的编码格式. b5~b1如果全为1,则说明这个tag下面还有一个子字节. 占两个字节, 否则tag占一个字节。

长度:

  长度(即L本身)的属性也为bit,占1~3个字节长度。具体编码规则如下:

  a)当L字段最左边字节的最左bit位(即bit8)为0,表示该L字段占一个字节,它的后续7个bit位(即bit7~bit1)表示取值的长度,采用二进制数表示取值长度的十进制数。

  b)当L字段最左边字节的最左bit位(即bit8)为1,表示该L字段不止占一个字节,那么它到底占几个字节由该最左字节的后续7个bit位(即bit7~bit1)的十进制取值表示。例如,若最左字节为10000010,表示L字段除该字节外,后面还有两个字节。其后续字节的十进制取值表示取值的长度。

附: java版的TLV解析:

package com.example.yang.myapplication.ans8583;

import java.util.ArrayList;
import java.util.List;

import static com.example.yang.myapplication.ans8583.Easy8583Ans.bytesToHexString;
import static com.example.yang.myapplication.ans8583.Easy8583Ans.hexStringToBytes;
import static java.lang.System.arraycopy;
/**

  • Created by yangyongzhen on 2018/07/07
  • simple TLV format Analysis
  • qq:534117529
    */
    public class TlvAns {

    class Tag{
    String tag;
    String length;
    String value;

    @Override
    public String toString() {
        return "Tag{" +
                "tag=‘" + tag + ‘\‘‘ +
                ", length=‘" + length + ‘\‘‘ +
                ", value=‘" + value + ‘\‘‘ +
                ‘}‘;
    }

    }

    Tag tag;
    List<Tag> tags;

    public TlvAns(){
    tags = new ArrayList<>();
    }

    void printTags(List<Tag> tags){
    for(Tag tag : tags){
    System.out.println(tag.toString());
    }
    }

    int pbocTlvAns( byte[] rxbuf, int rxsize )
    {
    int cout=0,n=0,num=0;
    //===========================================TLV解析
    while( cout < rxsize ) {
    if( ( ( (rxbuf[cout]&0xff) & 0x1F ) == 0x1F ) ) {
    //2字节Tag
    if( ( (rxbuf[cout]&0xff) == 0xBF ) && ( (rxbuf[cout+1]&0xff) == 0x0C ) ) {
    //=================================//模板
    //模板里的数据还需要进一步解析
    num = 0;
    }
    else {
    //=================================//标签
    num = 1;
    }
    tag = new Tag();
    tag.tag = String .format("%02x%02x",(rxbuf[cout]&0xff),(rxbuf[cout+1]&0xff));
    cout += 2;
    if( ( (rxbuf[cout]&0xff) & 0x80 ) == 0x80 ) {
    //=============================//长度为非1字节
    switch( (rxbuf[cout]&0xff) & 0x7F ) {
    //目前只处理最多2字节
    case 1:
    n = (rxbuf[cout+1]&0xff);
    tag.length = String.format("%02x%02x",(rxbuf[cout]&0xff),(rxbuf[cout+1]&0xff));
    cout += 2;
    break;
    case 2:
    n = ( ( (rxbuf[cout+1]&0xff) << 8 ) & 0xFF00 ) | (rxbuf[cout+2]&0xff);
    tag.length = String.format("%02x%02x%02x",rxbuf[cout]&0xff,rxbuf[cout+1]&0xff,rxbuf[cout+2]&0xff);
    cout += 3;
    break;
    // case 3:
    //n = ( ( rxbuf[cout+1] << 16 ) & 0xFF0000 ) | ( ( rxbuf[cout+2] << 8 ) & 0xFF00 ) | rxbuf[cout+3];
    //cout += 4;
    //break;
    default:
    //ErrMsg((U08)"L解析错误\r\n",strlen("L解析错误\r\n") );
    return 40;
    }
    }
    else {
    //=============================//长度为1字节
    n = (rxbuf[cout]&0xff);
    tag.length = String.format("%02x",n);
    cout += 1;
    }
    byte[] buffer = new byte[n];
    arraycopy(rxbuf,cout,buffer,0,n);
    tag.value = bytesToHexString(buffer);
    tags.add(tag);
    if( num == 0 ) {
    //=================================//模板
    //模板里的数据还需要进一步解析
    }
    else {
    //=================================//标签
    cout += n;
    }
    }
    else {
    //1字节T
    if( ( (rxbuf[cout]&0xff) >= 0x61 ) && ( (rxbuf[cout]&0xff) <= 0x7F ) )
    {//=================================//模板
    //模板里的数据还需要进一步解析
    num = 0;
    }
    else if( ( (rxbuf[cout]&0xff) == 0x80 ) || ( (rxbuf[cout]&0xff) == 0xA5 ) ) {
    //=================================//模板
    //模板里的数据还需要进一步解析
    num = 0;
    }
    else {
    //=================================//标签
    num = 1;
    }
    tag = new Tag();
    tag.tag = String .format("%02x",(rxbuf[cout]&0xff));
    cout++;
    if( ( (rxbuf[cout]&0xff) & 0x80 ) == 0x80 ) {
    //=============================//长度为非1字节
    switch( (rxbuf[cout]&0xff) & 0x7F ) {
    //目前只处理最多2字节
    case 1:
    n = (rxbuf[cout+1]&0xff);
    tag.length = String.format("%02x%02x",(rxbuf[cout]&0xff),(rxbuf[cout+1]&0xff));
    cout += 2;
    break;
    case 2:
    n = ( ( rxbuf[cout+1] << 8 ) & 0xFF00 ) | rxbuf[cout+2];
    tag.length = String.format("%02x%02x%02x",(rxbuf[cout]&0xff),(rxbuf[cout+1]&0xff),(rxbuf[cout+2]&0xff));
    cout += 3;
    break;
    // case 3:
    //n = ( ( rxbuf[cout+1] << 16 ) & 0xFF0000 ) | ( ( rxbuf[cout+2] << 8 ) & 0xFF00 ) | rxbuf[cout+3];
    //cout += 4;
    //break;
    default:
    //ErrMsg((U08
    )"L解析错误\r\n",strlen("L解析错误\r\n") );
    return 40;
    }
    }
    else {
    //=============================//长度为1字节
    n = (rxbuf[cout]&0xff);
    tag.length = String.format("%02x",n);
    cout += 1;
    }
    byte[] buffer = new byte[n];
    arraycopy(rxbuf,cout,buffer,0,n);
    tag.value = bytesToHexString(buffer);
    tags.add(tag);
    if( num == 0 ) {
    //=================================//模板
    //模板里的数据还需要进一步解析
    }
    else {
    //=================================//标签
    cout += n;
    }
    }
    }
    return 0;
    }

    public static void main(String[] args) {

    String hexstr = "776882027C009F3602004E57136212264200008234827D25062204329991635F9F101307010103A00000010A01000000000079B281999F2608DE242036EBF1B10B5F3401019F6C0220009F5D060000000000005F20142020202020202020202020202020202020202020";
    byte[] hexdata = hexStringToBytes(hexstr);
    
    TlvAns tlvAns = new TlvAns();
    //开始解析:
    tlvAns.pbocTlvAns(hexdata,hexdata.length);
    
    //打印出解析结果:
    tlvAns.printTags(tlvAns.tags);

    }
    }

输出结果:

Tag{tag=‘77‘,length=‘68‘, value=‘82027c009f3602004e57136212264200008234827d25062204329991635f9f101307010103a00000010a01000000000079b281999f2608de242036ebf1b10b5f3401019f6c0220009f5d060000000000005f20142020202020202020202020202020202020202020‘}
Tag{tag=‘82‘, length=‘02‘, value=‘7c00‘}
Tag{tag=‘9f36‘, length=‘02‘, value=‘004e‘}
Tag{tag=‘57‘, length=‘13‘, value=‘6212264200008234827d25062204329991635f‘}
Tag{tag=‘9f10‘, length=‘13‘, value=‘07010103a00000010a01000000000079b28199‘}
Tag{tag=‘9f26‘, length=‘08‘, value=‘de242036ebf1b10b‘}
Tag{tag=‘5f34‘, length=‘01‘, value=‘01‘}
Tag{tag=‘9f6c‘, length=‘02‘, value=‘2000‘}
Tag{tag=‘9f5d‘, length=‘06‘, value=‘000000000000‘}
Tag{tag=‘5f20‘, length=‘14‘, value=‘2020202020202020202020202020202020202020‘}

原文地址:http://blog.51cto.com/13860128/2139359

时间: 2024-10-13 06:13:52

java实现PBOC的TL分V分彩网站开发格式解析,超简单的解析的相关文章

Java实例详细五分彩网站开发讲解ArrayList用法

Java.util.ArrayList类是五分彩网站开发haozbbs.comQ1446595067一个动态数组类型,也就是说,ArrayList对象既有数组的特征,也有链表的特征.可以随时从链表中添加或删除一个元素.ArrayList实现了List接口. 大家知道,数组是静态的,数组被初始化之后,数组长度就不能再改变了.ArrayList是可以动态改变大小的.那么,什么时候使用Array(数组),什么时候使用ArrayList?答案是:当我们不知道到底有多少个数据元素的时候,就可使用Array

java虚拟机学习-JVM调优总结-分代垃圾回收详述(9)

为什么要分代 分代的垃圾回收策略,是基于这样一个事实:不同的对象的生命周期是不一样的.因此,不同生命周期的对象可以采取不同的收集方式,以便提高回收效率. 在Java程序运行的过程中,会产生大量的对象,其中有些对象是与业务信息相关,比如Http请求中的Session对象.线程.Socket连接,这类对象跟业务直接挂钩,因此生命周期比较长.但是还有一些对象,主要是程序运行过程中生成的临时变量,这些对象生命周期会比较短,比如:String对象,由于其不变类的特性,系统会产生大量的这些对象,有些对象甚至

android 布局页面文件出错故障排除Exception raised during rendering: java.lang.System.arraycopy([CI[CII)V

今天在看布局文件的时候出现 android 布局页面文件出错故障排除Exception raised during rendering: java.lang.System.arraycopy([CI[CII)V 提醒,google后在网上说是因为sdk版本的问题. 解决方法: 修改选择不同的API就好了,降低版本即可

How to solve Exception raised during rendering: java.lang.System.arraycopy([CI[CII)V in Android

android开发打开别人的项目的时候,手机面板上的控件有时候不能显示,还显示错误信息: Exception raised during rendering: java.lang.System.arraycopy([CI[CII)V Exception details are logged in Window > Show View > Error Log 原因是目前采用的API版本与原来的API版本不匹配,把API版本改一下即可.

Android的布局文件遇到Exception raised during rendering: java.lang.System.arraycopy([CI[CII)V问题

打开xml的布局文件,发现布局无法显示预览,而且报错:Exception raised during rendering: java.lang.System.arraycopy([CI[CII)V.原来是因为用了最新的API 20.这个是Android用于开发可穿戴设备的,不支持EditText.将API改为20之前的就行了.

InterviewQuestion_C#_Probl_计算1分2分5分硬币各有多少枚

题目:现在有1分.2分.5分硬币共100个,总金额为2.46元,请用程序计算出1分.2分.5分各有多少枚,有多少种算法? 这是最近面试遇到的一个题目,刚开始没有思路,一看这是一个三元一次方程组,假设个数分别为a.b.c的话,就会有三个未知数和两个方程组,怎么解?数学真是白学了! 于是在网上搜到了这个题目,不过题目略有不同: 文件:Program1.cs //问题:1分2分5分硬币,一共2.46元,求各种硬币的个数 //回答:你没说明是不是求需要的最少的硬币的个数,因为这样有上千种组成,所以我就给

ECLIPSE android 布局页面文件出错故障排除Exception raised during rendering: java.lang.System.arraycopy([CI[CII)V

在布局添加控件手动添加还是拖的添加,添加edittext后布局就不好用,其他控件好用,然后就说下面这段话 Exception raised during rendering: java.lang.System.arraycopy([CI[CII)V Exception details are logged in Window > Show View > Error Log Check the "Android version to use when rendering layouts

用1分,5分,10分,25分,50分硬币凑成一元,总共有几种组合办法?(SQL 谜题)

早在ITPUB中看过有个SQL高手,喜欢出谜题,以下是一个谜题.我试用SQL SERVER解决此问题. 用1分,5分,10分,25分,50分硬币凑成一元,总共有几种组合办法? SELECT'1*'+rtrim(a.number) +'+5*'+rtrim(b.number) +'+10*'+rtrim(c.number) +'+25*'+rtrim(d.number) +'+50*'+rtrim(e.number)AS result FROM(select number from master.

分钟数转换成倒计时,格式 _天_时_分

#region 分钟数转换成倒计时,格式 _天_时_分 + string MinutesToCountdown(int Minutes) /// <summary> /// 将分钟数转换成倒计时 格式:_天_时_分 /// </summary> /// <param name="Minutes">分钟数</param> /// <returns></returns> public static string Min