最近做电信预付费用户话单(ASN.1格式),由于需求比较急,客户要求尽快搞定。这几天忙的焦头烂额,几乎把google上能查到的asn1相关信息都试了一下,今天终于有了一点成就,并生成了个测试话单……
初次尝试:
(Java Asn1 Compiler(JAC)):由于只支持tag值 1-127,所以放弃
例子:
/**
* 话单头部
* @author mizhao
*
*/
public class HeaderNode extends Sequence {
/**
* 记录类型
*/
IA5String recordType = new IA5String("recordType");
/**
* 拜访局代码
*/
IA5String visitBureauCode = new IA5String("visitBureauCode");
/**
* 归属局代码
*/
IA5String belongBureauCode = new IA5String("belongBureauCode");
/**
* 文件序号
*/
IA5String serialNo = new IA5String("serialNo");
/**
* 文件产生日期(YYYYMMDDHHMISS)
*/
IA5String createDate = new IA5String("createDate");
/**
* 文件版本号
*/
IA5String versionNo = new IA5String("versionNo");
public HeaderNode(){
super();
setUpElements();
}
public HeaderNode(String name){
super(name);
setUpElements();
}
protected void setUpElements() {
super.addElement(recordType);
recordType.setTagClass(Tag.APPLICATION);
recordType.setTagNumber(ASN1TagConstants.TAG_RECORD_TYPE);
super.addElement(visitBureauCode);
visitBureauCode.setTagClass(Tag.APPLICATION);
visitBureauCode.setTagNumber(ASN1TagConstants.TAG_VISIT_BUREAU_CODE);
super.addElement(belongBureauCode);
belongBureauCode.setTagClass(Tag.APPLICATION);
belongBureauCode.setTagNumber(ASN1TagConstants.TAG_BELONG_BUREAU_CODE);
super.addElement(serialNo);
serialNo.setTagClass(Tag.APPLICATION);
serialNo.setTagNumber(ASN1TagConstants.TAG_SERIAL_NO);
super.addElement(createDate);
createDate.setTagClass(Tag.APPLICATION);
createDate.setTagNumber(ASN1TagConstants.TAG_CREATE_DATE);
super.addElement(versionNo);
versionNo.setTagClass(Tag.APPLICATION);
versionNo.setTagNumber(ASN1TagConstants.TAG_VERSION_NO);
}
}
测试方法:
//create header
headerNode.recordType.setValue("10");
headerNode.visitBureauCode.setValue("46003114");
headerNode.belongBureauCode.setValue("46003114");
headerNode.serialNo.setValue("1");
headerNode.createDate.setValue("20100817142800");
headerNode.versionNo.setValue("10");
ByteArrayOutputStream stream = new ByteArrayOutputStream();
BerOutputStream out = new BerOutputStream(stream);
headerNode.encode(out);
byte[] bytes = stream.toByteArray();
…………
最终定稿:
bouncycastle:
/**
* 话单记录
* @author mizhao
*
*/
public class BillingRecord extends DERSequence {
/**
* 计费号码
*/
DERIA5String servedNum;
/**
* 用户类型
*/
DERIA5String userType;
/**
* 呼叫类型记录类型
*/
DERIA5String callingType;
/**
* 用户拨打号码方式
*/
DERIA5String callingMeans;
/**
* 主叫号码
*/
DERIA5String callingNum;
/**
* 被叫号码
*/
DERIA5String calledNum;
/**
* 业务开始时间
*/
DERIA5String callBeginTime;
/**
* 业务结束时间
*/
DERIA5String callStopTime;
/**
* 使用时长
*/
DERIA5String callDuration;
/**
* 创建圈子数量
*/
DERInteger createCycleQuantity;
/**
* 圈子性质
*/
DERIA5String cycleAttr;
/**
* SP代码
*/
DERIA5String spCode;
/**
* 费用类型
*/
DERIA5String chargeType;
/**
* 费用
*/
DERInteger fee;
/**
* 优惠费用
*/
DERInteger discount;
public BillingRecord(String servedNum,String userType,String callingType,String callingMeans,String callingNum,String calledNum
,String callBeginTime,String callStopTime,String callDuration,int createCycleQuantity,String cycleAttr,String spCode
,String chargeType,int fee,int discount){
super();
this.servedNum = new DERIA5String(servedNum);
this.userType = new DERIA5String(userType);
this.callingType = new DERIA5String(callingType);
this.callingMeans = new DERIA5String(callingMeans);
this.callingNum = new DERIA5String(callingNum);
this.calledNum = new DERIA5String(calledNum);
this.callBeginTime = new DERIA5String(callBeginTime);
this.callStopTime = new DERIA5String(callStopTime);
this.callDuration = new DERIA5String(callDuration);
this.createCycleQuantity = new DERInteger(createCycleQuantity);
this.cycleAttr = new DERIA5String(cycleAttr);
this.spCode = new DERIA5String(spCode);
this.chargeType = new DERIA5String(chargeType);
this.fee = new DERInteger(fee);
this.discount = new DERInteger(discount);
setUpElements();
}
public void setUpElements(){
super.addObject(new DERTaggedObject(ASN1TagConstants.TAG_SERVED_NUM,servedNum));
super.addObject(new DERTaggedObject(ASN1TagConstants.TAG_USER_TYPE,userType));
super.addObject(new DERTaggedObject(ASN1TagConstants.TAG_CALLING_TYPE,callingType));
super.addObject(new DERTaggedObject(ASN1TagConstants.TAG_CALLING_MEANS,callingMeans));
super.addObject(new DERTaggedObject(ASN1TagConstants.TAG_CALLING_NUM,callingNum));
super.addObject(new DERTaggedObject(ASN1TagConstants.TAG_CALLED_NUM,calledNum));
super.addObject(new DERTaggedObject(ASN1TagConstants.TAG_CALLING_BEGIN_TIME,callBeginTime));
super.addObject(new DERTaggedObject(ASN1TagConstants.TAG_CALL_STOP_TIME,callStopTime));
super.addObject(new DERTaggedObject(ASN1TagConstants.TAG_CALL_STOP_TIME,callDuration));
super.addObject(new DERTaggedObject(ASN1TagConstants.TAG_CREATE_CYCLE_QUANTITY,createCycleQuantity));
super.addObject(new DERTaggedObject(ASN1TagConstants.TAG_CYCLE_ATTR,cycleAttr));
super.addObject(new DERTaggedObject(ASN1TagConstants.TAG_SP_CODE,spCode));
super.addObject(new DERTaggedObject(ASN1TagConstants.TAG_CHARGE_TYPE,chargeType));
super.addObject(new DERTaggedObject(ASN1TagConstants.TAG_FEE,fee));
super.addObject(new DERTaggedObject(ASN1TagConstants.TAG_DISCOUNT,discount));
}
}
注:ASN1TagConstants中的常量可以自定义
测试方法:
public static BillingRecord createData(String servedNum,String userType,String callingType,String callingMeans,String callingNum,String calledNum
,String callBeginTime,String callStopTime,String callDuration,int createCycleQuantity,String cycleAttr,String spCode
,String chargeType,int fee,int discount){
BillingRecord billingRecord = new BillingRecord(servedNum, userType, callingType, callingMeans, callingNum, calledNum, callBeginTime, callStopTime, callDuration, createCycleQuantity, cycleAttr, spCode, chargeType, fee, discount);
return billingRecord;
}
public static void main(String[] args) throws Exception {
//数据信息(功能费)
BillingRecord billingRecord = createData("13379035182","1","20","1","13379035182","1188913379035182","20100817142800","20100817142800","0",1,"1","10659181","2",5000,0);
// ByteArrayOutputStream bOut = new ByteArrayOutputStream();
// DEROutputStream dOut = new DEROutputStream(bOut);
// dOut.writeObject(billingRecord );
// byte[] bytes = bOut.toByteArray();
}