自定义8583模板,打包解包,使用j8583包有改动
j8583_boss.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE j8583-config PUBLIC "-//J8583//DTD CONFIG 1.0//EN"
"C:/tvpay/config/j8583.dtd">
<j8583-config>
<!-- These are the ISO headers to be prepended to the message types specified -->
<header type="1027">1027</header>
<header type="1028">1028</header>
<header type="1005">1005</header>
<header type="1006">1006</header>
<!-- The server example uses this to read the requests -->
<parse type="1027">
<field num="2" type="LLVAR" />
<field num="3" type="LLVAR" />
<field num="4" type="NUMERIC" length="4" />
<field num="5" type="NUMERIC" length="4" />
<field num="6" type="NUMERIC" length="4" />
<field num="7" type="NUMERIC" length="1" />
<field num="8" type="NUMERIC" length="1" />
<field num="43" type="LLVAR" />
<field num="44" type="LLVAR" />
<field num="45" type="LLVAR" />
</parse>
<parse type="1005">
<field num="2" type="LLVAR" />
<field num="3" type="LLVAR" />
<field num="4" type="NUMERIC" length="4" />
<field num="5" type="NUMERIC" length="4" />
<field num="6" type="NUMERIC" length="4" />
<field num="7" type="NUMERIC" length="1" />
<field num="8" type="NUMERIC" length="1" />
<field num="19" type="LLVAR" />
<field num="21" type="LLVAR" />
<field num="23" type="ALPHA" length="2" />
<field num="24" type="LLVAR" />
<field num="27" type="LLVAR" />
<!-- <field num="39" type="NUMERIC" length="6" /> -->
</parse>
<!-- The client example uses this to read the responses -->
<parse type="1028">
<field num="2" type="LLVAR" />
<field num="3" type="LLVAR" />
<field num="4" type="NUMERIC" length="4" />
<field num="5" type="NUMERIC" length="4" />
<field num="6" type="NUMERIC" length="4" />
<field num="7" type="NUMERIC" length="1" />
<field num="8" type="NUMERIC" length="1" />
<field num="41" type="LLLVAR" />
<field num="43" type="LLVAR" />
<field num="44" type="LLVAR" />
<field num="45" type="LLVAR" />
</parse>
<parse type="1006">
<field num="2" type="LLVAR" />
<field num="3" type="LLVAR" />
<field num="4" type="NUMERIC" length="4" />
<field num="5" type="NUMERIC" length="4" />
<field num="6" type="NUMERIC" length="4" />
<field num="7" type="NUMERIC" length="1" />
<field num="8" type="NUMERIC" length="1" />
<field num="19" type="LLVAR" />
<field num="20" type="LLVAR" />
<field num="21" type="LLVAR" />
<field num="22" type="LLVAR" />
<field num="23" type="ALPHA" length="2"/>
<field num="24" type="LLVAR" />
<field num="27" type="LLVAR" />
<field num="29" type="NUMERIC" length="10" />
</parse>
</j8583-config>
package com.sumavision.connector.iso8583.parse;
import java.io.*;
import java.util.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.io.Resource;
import com.sumavision.connector.iso8583.util.ConfigParser;
import com.sumavision.connector.iso8583.util.IsoValue;
import com.sumavision.connector.iso8583.util.MessageFactory;
import com.sumavision.connector.iso8583.util.SimpleTraceGenerator;
import com.sumavision.connector.iso8583.util.IsoMessage;
import com.sumavision.connector.iso8583.util.IsoType;
import com.sumavision.connector.util.DesEncrypt;
import com.sumavision.connector.util.Hex2GBKStringUtil;
import com.sumavision.connector.util.PacketIdGenerator;
import com.sumavision.connector.util.RequestIdGenerator;
import com.sumavision.crpt.MessageDigestMD5;
/**
* <p>数据打包解包服务</p>
* @author Administrator
*/
public class PacketDataOperateService {
private final Logger log = LoggerFactory.getLogger(this.getClass());
//模板文件配置路径
private final String OPERATE_TEMPLATE_PATH = "com/sumavision/connector/iso8583/parse/j8583_boss.xml";
private Resource templatePath = null;
//获取用户信息(终端号) 支付平台传来的交易代码
private final String GET_TERMINALNO_TRANSCODE = "BT000201";
//获取用户缴费账单(BOSS缴费单) 支付平台传来的交易代码
private final String GET_USERFEE_TRANSCODE = "BT000202";
//获取用户信息(终端号) 功能码
private final int GET_TERMINALNO_FUNCNO = 1027;
//获取用户信息(终端号) 返回响应功能码
private final int GET_TERMINALNO_RESPONSE_FUNCNO =1028;
//获取用户缴费账单(BOSS缴费单) 功能码
private final int GET_USERFEE_FUNCNO = 1005;
//获取用户缴费账单(BOSS缴费单) 返回响应功能码
private final int GET_USERFEE_RESPONSE_FUNCNO = 1006;
//机顶盒内部编码
private final String STB_INSIDE_CODE = "STB_INSIDE_CODE";
//厂商编号
private final String MANUFACTURERS_NO = "MANUFACTURERS_NO";
//硬件版本号
private final String HARDWARE_VERSION_NO = "HARDWARE_VERSION_NO";
//客户编码
private final String CUSTOMER_NO = "CUSTOMER_NO";
//账户编码
private final String ACCOUNT_NO = "ACCOUNT_NO";
//业务编码
private final String SERVICE_TYPE = "SERVICE_TYPE";
//服务号码
private final String SUBSCRIBER_NO = "SUBSCRIBER_NO";
//账务周期
private final String BILLING_CYCLE = "BILLING_CYCLE";
//开始标识+包长度+包体+校验字段+结束标识
//报文开始标识
private final String PACKET_HEADER = "|*!#";
//报文结束标识
private final String PACKET_TAILER = "#@&^";
private static final Map<String,String> retCodeMsgMap = new HashMap<String,String>();
/*初始化错误代码表*/
static{
retCodeMsgMap.put("0000", "交易成功");
retCodeMsgMap.put("0001", "服务器忙");
retCodeMsgMap.put("0002", "无法解析字符串");
retCodeMsgMap.put("0003", "SMS系统内部错误");
retCodeMsgMap.put("0004", "版本号不支持");
retCodeMsgMap.put("0005", "数据库没有该银行的记录");
retCodeMsgMap.put("0006", "银行代码与银行认证码不符");
retCodeMsgMap.put("0007", "客户编码不存在");
retCodeMsgMap.put("0008", "帐户编码不存在");
retCodeMsgMap.put("0009", "业务编码不存在");
retCodeMsgMap.put("0010", "服务号码不存在");
retCodeMsgMap.put("0011", "账务周期不存在");
retCodeMsgMap.put("0012", "银行流水号不存在");
retCodeMsgMap.put("0013", "余额账本不存在");
retCodeMsgMap.put("0014", "存在多个余额账本,请按余额账本编号查询");
retCodeMsgMap.put("0015", "存在一个服务号码由多个客户的帐户付费");
retCodeMsgMap.put("0016", "已缴费");
retCodeMsgMap.put("0017", "已签订代扣协议");
retCodeMsgMap.put("0018", "此帐户未使用该流水号签订代扣协议");
retCodeMsgMap.put("0019", "此客户有多个帐户,请使用帐户编号");
retCodeMsgMap.put("0020", "预存失败,预存超过余额上限");
retCodeMsgMap.put("0021", "实缴金额不等于实际费用加滞纳金");
retCodeMsgMap.put("0022", "冲正失败");
retCodeMsgMap.put("0023", "已经对账,不能进行冲正");
retCodeMsgMap.put("0024", "已经冲正,不能再次冲正");
retCodeMsgMap.put("0025", "必填数据未填充");
retCodeMsgMap.put("0026", "代扣失败");
retCodeMsgMap.put("0027", "发票号码不存在");
retCodeMsgMap.put("0028", "发票号码不可使用");
retCodeMsgMap.put("0029", "附加信息域格式错误");
retCodeMsgMap.put("0030", "产品信息域格式错误");
retCodeMsgMap.put("0032", "找不到对应用户");
}
/**
* <p>打包数据</p>
* @param map
* @return
* @throws Exception
*/
public String packetData(Map<String, Object> map) throws Exception{
log.info("打包数据准备...Map >>{}",map);
if(null==map || map.size()<1){
log.error("请求参数域为空,打包失败");
return null;
}
if (!map.containsKey("STB_ID")) {
log.error("请求参数STB_ID域为空,打包失败");
return null;
}
String stb = map.get("STB_ID").toString();
map.put("MANUFACTURERS_NO", stb.substring(0, 3));
map.put("HARDWARE_VERSION_NO", stb.substring(3, 18));
map.put("STB_INSIDE_CODE", stb.substring(18, 25));
MessageFactory mfact = ConfigParser.createFromStream(templatePath.getInputStream());
// MessageFactory mfact = ConfigParser.createFromClasspathConfig(templatePath.);
// mfact.setAssignDate(true);
// mfact.setTraceNumberGenerator(new SimpleTraceGenerator((int)(System.currentTimeMillis() % 100000)));
String transcode = (String)map.get("TRANSCODE");
IsoMessage m = null;
if(null!=transcode && transcode.equals(GET_TERMINALNO_TRANSCODE)){
m= _cardNumberForMachinePacket(map,mfact);
}else if(null!=transcode && transcode.equals(GET_USERFEE_TRANSCODE)){
m= _accessToUserFeesBillPacket(map,mfact);
}else{
log.error("交易代码错误,打包失败");
return null;
}
String packetStr = new String(m.writeData());
String packetLenStr = String.valueOf(packetStr.length()+32);
StringBuffer sbuff = new StringBuffer();
sbuff.append(PACKET_HEADER);
if(packetLenStr.length()<8){
sbuff.append("00000000".substring(packetLenStr.length()));
}
sbuff.append(packetStr.length()+32);
sbuff.append(packetStr);
sbuff.append(generateValidateCode(packetStr).toLowerCase());
sbuff.append(PACKET_TAILER);
log.info("打包数据完成...报文 >>{}",sbuff.toString());
return sbuff.toString();
}
/**
* <p>解析报文字符串</p>
* @param pstr 报文体
* @param vstr 校验字段
* @return
* @throws Exception
*/
@SuppressWarnings("rawtypes")
public Map parseData(String pstr,String vstr,int funcCode) throws Exception{
log.info("解包数据准备...报文体 >>{}",pstr);
log.info("解包数据准备...报文校验字段 >>{}",vstr);
MessageFactory mfact = ConfigParser.createFromStream(templatePath.getInputStream());
// MessageFactory mfact = ConfigParser.createFromClasspathConfig(templatePath);
// mfact.setAssignDate(true);
// mfact.setTraceNumberGenerator(new SimpleTraceGenerator((int)(System.currentTimeMillis() % 100000)));
mfact.setUseBinaryMessages(false);
//可能有中文
// String bstr = new String(bytes,"GBK");
// int functionCode = Integer.valueOf(pstr.substring(68, 72));
// String packetDataStr = bstr.substring(12, bstr.length()-4-32);
// String validateStr = bstr.substring(bstr.length()-4-32, bstr.length()-4);
Map map = null;
byte[] packetBytes = pstr.getBytes("GBK");
if(funcCode==GET_TERMINALNO_RESPONSE_FUNCNO){
if(!validateResponseData(pstr,vstr)){
throw new Exception("数据包校验失败,无效数据包");
}
map = cardNumberForMachinePacket_(mfact.parseMessage(packetBytes, 4136));
}else if(funcCode==GET_USERFEE_RESPONSE_FUNCNO){
//查询单用户余额账本的 返回报文中含有中文字符,返回的校验码与对报文做MD5生成的校验码不一致
//未找到原因: 暂时不做校验
map = accessToUserFeesBillPacket_(mfact.parseMessage(packetBytes, 4102));
}else{
log.error("无法识别的功能码,解包失败");
return null;
}
log.info("解包数据完成...Map >>{}",map);
return map;
}
/**
* 打包
* @param mf
* @param input
* @return
*/
@SuppressWarnings("rawtypes")
private IsoMessage _cardNumberForMachinePacket(Map input,MessageFactory mf){
// IsoMessage m = mf.newMessage(GET_TERMINALNO_FUNCNO);
IsoMessage m = new IsoMessage();
m.setBinary(false);
// m.setBinary(true);
//会话ID 对来自银行前置机接入SMS的请求数据,此处填写由银行前置机产生的会话ID,在传输过程中应保持一对请求/响应的数据中 SessionID 保持不变
m.setValue(2, RequestIdGenerator.genRequestId(), IsoType.LLVAR, 16);
//数据包序号 从 0 开始,顺序累加,步长为 1,循环使用
m.setValue(3, PacketIdGenerator.genPacketId(), IsoType.LLVAR, 32);
//银行代码 暂时不知道,先写1111
m.setValue(4, 2000, IsoType.NUMERIC, 4);
//功能码 业务标识,用于标识请求/响应数据包代表的业务操作
m.setValue(5, GET_TERMINALNO_FUNCNO, IsoType.NUMERIC, 4);
//响应吗 标识业务处理结果
m.setValue(6, 0000, IsoType.NUMERIC, 4);
//重发标识 0 标识普通数据包;1:标识重发数据包
m.setValue(7, 0, IsoType.NUMERIC, 1);
//加密标识 0 标识包体数据为明文,1:标识包体数据为加密数据
m.setValue(8, 0, IsoType.NUMERIC, 1);
//机顶盒内部编码 StbInsideCode
m.setValue(43, input.get(STB_INSIDE_CODE), IsoType.LLVAR, 50);
//厂商编号 ManufacturersNo
m.setValue(44, input.get(MANUFACTURERS_NO), IsoType.LLVAR, 20);
//硬件版本号 HardwareVersionNo
m.setValue(45, input.get(HARDWARE_VERSION_NO), IsoType.LLVAR, 20);
return m;
}
/**
* 打包
* @param mf
* @param input
* @return
*/
@SuppressWarnings("rawtypes")
private IsoMessage _accessToUserFeesBillPacket(Map input,MessageFactory mf){
IsoMessage m = mf.newMessage(GET_USERFEE_FUNCNO);
m.setBinary(false);
//会话ID 对来自银行前置机接入SMS的请求数据,此处填写由银行前置机产生的会话ID,在传输过程中应保持一对请求/响应的数据中 SessionID 保持不变
m.setValue(2, RequestIdGenerator.genRequestId(), IsoType.LLVAR, 16);
//数据包序号 从 0 开始,顺序累加,步长为 1,循环使用
m.setValue(3, PacketIdGenerator.genPacketId(), IsoType.LLVAR, 32);
//银行代码 暂时不知道,先写1111
m.setValue(4, 2000, IsoType.NUMERIC, 4);
//功能码 业务标识,用于标识请求/响应数据包代表的业务操作
m.setValue(5, GET_USERFEE_FUNCNO, IsoType.NUMERIC, 4);
//响应吗 标识业务处理结果
m.setValue(6, 0000, IsoType.NUMERIC, 4);
//重发标识 0 标识普通数据包;1:标识重发数据包
m.setValue(7, 0, IsoType.NUMERIC, 1);
//加密标识 0 标识包体数据为明文,1:标识包体数据为加密数据
m.setValue(8, 0, IsoType.NUMERIC, 1);
//客户编码 CustomerNo 广电客户的编码
m.setValue(19, input.get(CUSTOMER_NO), IsoType.LLVAR, 20);
//下面3项必填一项
if(null!=input.get(ACCOUNT_NO)){
//账户编码 AccountNo 广电客户的帐户编码
m.setValue(21, input.get(ACCOUNT_NO), IsoType.LLVAR, 20);
}
if(null!=input.get(SERVICE_TYPE)){
//业务编码 ServiceType 公共业务00 数字电视业务02
m.setValue(23, input.get(SERVICE_TYPE), IsoType.ALPHA, 2);
}
if(null!=input.get(SUBSCRIBER_NO)){
//服务号码 SubscriberNo 智能卡号、上网帐号等
m.setValue(24, input.get(SUBSCRIBER_NO), IsoType.LLVAR, 20);
}
//账务周期 BillingCycle 可选
// m.setValue(39, input.get(BILLING_CYCLE), IsoType.LLVAR, 20);
return m;
}
/**
* 解包
* @param im
* @return
*/
@SuppressWarnings({ "rawtypes", "unchecked" })
private Map cardNumberForMachinePacket_(IsoMessage im){
log.info("cardNumberForMachinePacket_ : receive Msg :"+printIsoMessage(im));
//银行代码
IsoValue bankCode = im.getAt(4);
//功能码
IsoValue functionCode = im.getAt(5);
//boss响应吗
IsoValue retCode = im.getAt(6);
//加密标识
IsoValue isEncrpt = im.getAt(8);
//机顶盒内部编码
IsoValue stbInsideCode = im.getAt(43);
//厂商编码
IsoValue manufacturersNo = im.getAt(44);
//硬件版本号
IsoValue hardwareVersionNo = im.getAt(45);
//附件信息 响应中的“附加信息”域经过加密处理,加密方式会通过其他方式告知。其中的内容如下:
//智能卡号/t 客户ID/t 用户ID/t 客户姓名/t 客户地址例如:
//1234567890 1521 1598 张三 天津市河西区气象台路卫星里
IsoValue additionalData = im.getAt(41);
if(!String.valueOf(functionCode.getValue()).equals(String.valueOf(GET_TERMINALNO_RESPONSE_FUNCNO))){
log.error("功能码不正确");
}
Map map = new HashMap();
map.put("RETCODE", retCode.getValue());
map.put("TRANSMSG", getTransMsg(paddingRetCode(String.valueOf(retCode.getValue()))));
// map.put("BANK_CODE", bankCode.getValue());
map.put("IS_ENCRPT", isEncrpt.getValue());
map.put("STB_INSIDE_CODE", stbInsideCode.getValue());
map.put("MANUFACTURERS_NO", manufacturersNo.getValue());
map.put("HARDWARE_VERSION_NO", hardwareVersionNo.getValue());
map.put("ADDITIONAL_DATA", additionalData.getValue());
Object addData = additionalData.getValue();
//additionalData解密
String additional_Str = null;
if(null!=addData){
String raw_additional_Str = decrptDesString(String.valueOf(addData));
if(null!=raw_additional_Str){
additional_Str = Hex2GBKStringUtil.toStringHex(raw_additional_Str);
log.info("HEX字符串转为GBK文本串为 /n {}",additional_Str);
}
}
try{
String[] infos = parseAdditionalInfo(additional_Str);
//智能卡号
map.put("ICCARD_ID", infos[0]);
//客户ID
map.put("CUSTOMER_ID", infos[1]);
//用户ID
map.put("USER_ID", infos[2]);
//客户姓名
map.put("CUSTOMER_NAME", infos[3]);
//客户地址
map.put("USER_ADDRESS", infos[4]);
}catch(Exception e){
log.error("解析附加信息失败 , 原因: {}",e);
//智能卡号
map.put("ICCARD_ID", null);
//客户ID
map.put("CUSTOMER_ID", null);
//用户ID
map.put("USER_ID", null);
//客户姓名
map.put("CUSTOMER_NAME", null);
//客户地址
map.put("USER_ADDRESS", null);
}
return map;
}
/**
* 解包
* @param im
* @return
*/
@SuppressWarnings({ "rawtypes", "unchecked" })
private Map accessToUserFeesBillPacket_(IsoMessage im){
log.info("accessToUserFeesBillPacket_ : receive Msg :"+printIsoMessage(im));
//银行代码
IsoValue bankCode = im.getAt(4);
//功能码
IsoValue functionCode = im.getAt(5);
//boss响应吗
IsoValue retCode = im.getAt(6);
//加密标识
IsoValue isEncrpt = im.getAt(8);
//客户编码
IsoValue customerNo = im.getAt(19);
//客户名称
IsoValue customerName = im.getAt(20);
//账户编码
IsoValue accountNo = im.getAt(21);
//帐户名称
IsoValue accountName = im.getAt(22);
//业务编码
IsoValue serviceType = im.getAt(23);
//服务号码
IsoValue subscriNo = im.getAt(24);
//余额
IsoValue balance = im.getAt(29);
if(!String.valueOf(functionCode).equals(String.valueOf(GET_USERFEE_RESPONSE_FUNCNO))){
log.error("功能码不正确");
}
Map map = new HashMap();
map.put("RETCODE", retCode.getValue());
map.put("TRANSMSG", getTransMsg(paddingRetCode(String.valueOf(retCode.getValue()))));
// map.put("BANK_CODE", bankCode.getValue());
map.put("IS_ENCRPT", isEncrpt.getValue());
map.put("CUSTOMER_NO", customerNo.getValue());
map.put("CUSTOMER_NAME", customerName.getValue());
map.put("BALACNE", balance==null?null:balance.getValue());
return map;
}
/**
* <p>校验响应数据包的校验码是否正确</p>
* @param rawData 待校验数据串
* @param validateCode 校验码
* @return
*/
private boolean validateResponseData(String rawData,String validateCode){
return validateCode.equals(MessageDigestMD5.keyedEncode(rawData, ""));
}
/**
* <p>获取返回码对应的消息</p>
* @param code
* @return
*/
private String getTransMsg(String code){
if(retCodeMsgMap.containsKey(code)){
return retCodeMsgMap.get(code);
}else{
return "交易失败";
}
}
private String paddingRetCode(String rawcode){
if(rawcode.length()<4){
return "0000".substring(rawcode.length())+rawcode;
}else{
return rawcode;
}
}
/**
* <p>解密DES加密串</p>
* @param rawData
* @return
* @throws Exception
*/
private String decrptDesString(String rawData) {
String rstr = null;
log.info("DES解密算法解密源字符串: /n {}",rawData);
if(null==rawData){
log.error("源加密字符串为空!");
return null;
}
try {
// 设置密钥 静态,设置一次即可 密钥是固定的,写死即可
DesEncrypt.setKey("A000000000000000");
rstr = DesEncrypt
.desDecrypt(rawData);
} catch (Exception e) {
log.error("DES解密算法 解密密码串失败, 原因: {}",e);
}
log.info("DES解密算法解密结果: /n {}",rstr);
return rstr;
}
private String printIsoMessage(IsoMessage m) {
StringBuffer sbuff = new StringBuffer();
sbuff.append("TYPE: " + Integer.toHexString(m.getType()) +" /n");
for (int i = 2; i < 128; i++) {
if (m.hasField(i)) {
sbuff.append("F " + i + "(" + m.getField(i).getType() + "): " + m.getObjectValue(i) + " -> '"
+ m.getField(i).toString() + "' /n");
}
}
return sbuff.toString();
}
/**
* <p>解密附加信息
* 用于 解析 根据机顶盒号查询用户响应
* </p>
* @param s
* @return [0] 智能卡号
* [1] 客户ID
* [2] 用户ID
* [3] 客户姓名
* [4] 客户地址
* @throws Exception
*/
private String[] parseAdditionalInfo(String s) throws Exception{
if(null!=s && !"".equals(s)){
String[] ss = s.trim().split("//t");
if(ss.length!=5){
throw new Exception("解析附加信息失败,信息格式不正确!");
}else{
return new String[]{ss[0].trim(),ss[1].trim(),ss[2].trim(),ss[3].trim(),ss[4].trim()};
}
}else{
throw new Exception("解析附加信息失败,信息格式不正确!");
}
}
/**
* <p>发送报文时生成校验码</p>
* @param rawData
* @return
*/
private String generateValidateCode(String rawData){
return MessageDigestMD5.keyedEncode(rawData, "");
}
public static void main(String[] strs) throws Exception{
PacketDataOperateService pd = new PacketDataOperateService();
// System.out.println(pd.generateValidateCode("7F003E28000000001613039575047501073200000000000000000000000000000006200010060000001210600001287906傅雪晶1200000301582511傅雪晶-帐户00120000030158250000067062"));
// System.out.println(pd.generateValidateCode("12345678901234567890").length());
String r = pd.decrptDesString("3EE1B1F40175DC92701588F6F40A7762B05859FACE94BA7CD7EC5513E4DBE3C519CD9BFF085642C765BDAD8F06D719F5A75161E54ACF5230BBD811E91E00A6A1C7FE957F19AEF1F6");
String additional_Str = Hex2GBKStringUtil.toStringHex(r);
String[] ss = pd.parseAdditionalInfo(additional_Str);
for(String s : ss){
System.out.println(s);
}
//System.out.println(pd.paddingRetCode("3"));
}
public Resource getTemplatePath() {
return templatePath;
}
public void setTemplatePath(Resource templatePath) {
this.templatePath = templatePath;
}
}
自定义8583模板,打包解包,使用j8583包有改动相关推荐
- 自定义8583模板,打包解包,使用j8583包
j8583_boss.xml <?xml version="1.0" encoding="UTF-8"?> <?xml version=&qu ...
- tar ,cpio打包解压. shell脚本for,while,until循环. rpm包管理,select循环菜单,函数function,yum...
tar tar -cf 路径+文件名字后续.tar +路径 创建归档压缩 tar cf /testdir/etc.tar /etc/ tar cvf 可以查看解压过程 tar tvf 预览作用 t ...
- Mtk Android 打包解包*.img
打包/解包 boot.img, system.img, userdata.img, or recovery.img [DESCRIPTION] MTK codebase编译出来的image必须使用MT ...
- html 自定义打印模板,HTML+CSS入门 自定义模板详解
本篇教程介绍了HTML+CSS入门 自定义模板详解,希望阅读本篇文章以后大家有所收获,帮助大家HTML+CSS入门.< 首先总的stylecss和大模板都是当初angel_Kitty学姐的,嗯, ...
- Android 系统(138 )---Mtk平台 Android 打包解包*.img ,修改system.img 参数
Mtk平台 Android 打包解包*.img ,修改system.img 参数 MTK 升级包文件如下: 若存在软件版本号存在错误或需要修改,重新编译则需要几个小时,或者要几天的测试 若可以直接修改 ...
- Android 系统(137)---android打包解包boot.img,system.img
android打包解包boot.img,system.img 2017年04月28日 15:00:36 阅读数:1822 原帖地址:http://www.52pojie.cn/thread-48802 ...
- tar打包/解包用法
eg: 打包: tar -zcvf alltxt.tar.gz *.txt 解包: tar -zxvf alltxt.tar.gz 通过SSH访问服务器,难免会要用到压缩,解压缩,打包,解包等,这时候 ...
- android自定义UI模板图文详解
不知道大家在实际开发中有没有自定义过UI模板?今天花时间研究了一下android中自定义UI模板,与大家分享一下. 每个设计良好的App都是自定义标题栏,在自定义标题栏的过程中大部分人可能都是自定义一 ...
- 安卓8.X解包打包工具和教程,windows平台一键打包解包工具
ROM制作工具在上周独家适配了安卓8.X的解包打包功能,很多朋友对这个功能翘首以盼,历经一个月的适配完善,得到了广泛认可. 软件是免费使用的哦! ROM制作工具目前已经是windows下最强大的一键解 ...
最新文章
- BAPC2014 Bamp;amp;HUNNU11582:Button Bashing(BFS)
- java 方法不同_java同一个类不同方法间的同步
- Ngrok: 使用 Ngrok 实现内网穿透
- python从url获取pdf文件并保存在本地
- 2017 Multi-University Training Contest - Team 1
- 该来的终于来了:“第一起”基于 IPv6 的 DDoS 攻击
- k8s部署nexus3
- modelform 对象和model之间的关系
- c语言 树的遍历,c语言构造树及树的三种遍历
- Java逐帧动画播放器V0.1.0
- 用js把数字转化成为大写金额
- 计算机编号、硬盘序列号和Mac地址查询方法
- Excel绘制双坐标抽图表
- 软件测试工程师必备技能
- 计算机学院软件设计比赛作品,计算机学院成功举办首届软件设计大赛
- Golang使用mgo.v2包操作MongoDB的基础示例
- python模型预测_用Python如何进行预测型数据分析
- 专注B2B跨境支付的背后,XTransfer的风控基础设施是如何炼成的?
- 按键精灵找图并点击图片中间
- %3c大自然的语言%3e竺可桢题目,大自然的语言 竺可桢阅读附答案
热门文章
- 交叉编译使用 hostapd-2.0 在开发板上开机自启动无线网卡 AP 功能
- 【pion】ice-single-port解析
- 基于智能手机的加速计进行计步实现。
- 回归方程的拟合优度检验_判定一元线性回归方程拟合优度的判定系数R的取值范围...
- docker版mongodb数据同步到elasticsearch
- 文本编辑器EditPlus
- 数据预处理 拉依达准则 matlab,数学建模数据预处理.doc
- 关于大学中软件工程课程的开设问题——不要把实践性科学当作理论性学科来教授...
- w ndows7怎样连接无线网,windows7电脑上连接wifi的设置步骤
- bootrom的类型