zoukankan      html  css  js  c++  java
  • ANSI X9.8标准 PIN xor PAN获取PIN BlOCK

    (1) ANSI X9.8 Format(不带主账号信息)

    PIN(个人识别码 Personal Identity Number)总共有8个byte长度,分为两个部分;(类似数据包的格式)

    1:Byte1 记录PIN的长度

    2:Byte2-Byte8 6-12位(字符)PIN(每个字符占4个BIT,不足8位右补F)

    例如:明文PIN为 123456,

    则PIN BLOCK为 0x06 0x12 0x34 0x56 0xFF 0xFF 0xFF 0xFF

    0x06记录了PIN的长度为6,后边不足16位均以F补齐,然后转换为BCD码(BCD码为8位二进制数为一个单元,也就是一个Byte的大小也是一个十六进制数HEX的占用长度)。

    2)ANSI X9.8 Format带主帐号信息)
    PIN BLOCK 格式:等于 PIN 按位异或主帐号
    PIN 格式:(与1中的格式类似)
    Byte 1 PIN的长度
    Byte 2 – Byte 3/4/5/6/7 4--12个PIN(每个PIN占4个BIT)
    Byte4/5/6/7/8 – Byte 8 FILLER “F” (每个“F“占4个BIT)

    PAN(主帐号 Primary Account Number)同样包含8个byte,格式如下:
    Byte 1 — Byte 2 0x00 0x00
    Byte 3 — Byte 8 12个主帐号字符(最后一位为校验位)
    12位字符主帐号的取法:
    取主帐号的右12位(不包括最右边的校验位),不足12位左补“0X00”。


    例子:

    明文 PIN:123456,
    主帐号 PAN:123456789012345678
    截取下的主帐号为:678901234567 (最后一位校验位8的前12位字符为截取的主帐号)

    则用于PIN加密的主帐号为:0x00 0x00 0x67 0x89 0x01 0x23 0x45 0x67
    则 PIN BLOCK (PIN按位异或主帐号PAN)

    即是为:  0x06 0x12 0x34 0x56 0xFF 0xFF 0xFF 0xFF
    异或上:  0x00 0x00 0x67 0x89 0x01 0x23 0x45 0x67
    结果为:  0x06 0x12 0x53 0xDF 0xFE 0xDC 0xBA 0x98

    算法源码:(包含一个工具类Util和一个转换类ANSIFormat.java)

    Util.java

    package CodeApe;

    public class Util {
     public Util() {

     }

     
     public static void printHexString(String hint, byte[] b) {
         System.out.print(hint);
         for (int i = 0; i < b.length; i++) {
           String hex = Integer.toHexString(b[i] & 0xFF);
           if (hex.length() == 1) {
             hex = '0' + hex;
           }
           System.out.print(hex.toUpperCase() + " ");
         }
         System.out.println("");
       }

     
     
    public static String Bytes2HexString(byte[] b) {
         String ret = "";
         for (int i = 0; i < b.length; i++) {
           String hex = Integer.toHexString(b[i] & 0xFF);
           if (hex.length() == 1) {
             hex = '0' + hex;
           }
           ret += hex.toUpperCase();
         }
         return ret;
       }

     
     
    public static byte uniteBytes(byte src0, byte src1) {
      byte _b0 = Byte.decode("0x" + new String(new byte[] { src0 }))
        .byteValue();
      _b0 = (byte) (_b0 << 4);
      byte _b1 = Byte.decode("0x" + new String(new byte[] { src1 }))
        .byteValue();
      byte ret = (byte) (_b0 ^ _b1);
      return ret;
     }

     
     public static byte[] HexString2Bytes(String src) {
      byte[] ret = new byte[8];
      byte[] tmp = src.getBytes();
      for (int i = 0; i < 8; i++) {
      
     ret[i] = uniteBytes(tmp[i * 2], tmp[i * 2 + 1]);
      }
      return ret;
     }

    }

    ANSIFormat.java

    package CodeApe;

    import java.io.ObjectInputStream.GetField;

    import javax.annotation.processing.Processor;

    import CodeApe.Util;

    public class ANSIFormat {

     private String pin;
     private String accno;
     public ANSIFormat(String pin , String accno){
      this.pin = pin;
      this.accno = accno;
     }
     
     public byte[] process(String pin, String accno) {
         byte arrPin[] = getHPin(pin);
         byte arrAccno[] = getHAccno(accno);
         byte arrRet[] = new byte[8];
         //PIN BLOCK 格式等于 PIN 按位异或 主帐号;
         for (int i = 0; i < 8; i++) {
           arrRet[i] = (byte) (arrPin[i] ^ arrAccno[i]);
         }
        
         Util.printHexString("PinBlock:", arrRet);
         return arrRet;
     }

     
     private byte[] getHPin(String pin) {
         byte arrPin[] = pin.getBytes();
         byte encode[] = new byte[8];
         encode[0] = (byte) 0x06;
         encode[1] = (byte) Util.uniteBytes(arrPin[0], arrPin[1]);
         encode[2] = (byte) Util.uniteBytes(arrPin[2], arrPin[3]);
         encode[3] = (byte) Util.uniteBytes(arrPin[4], arrPin[5]);
         encode[4] = (byte) 0xFF;
         encode[5] = (byte) 0xFF;
         encode[6] = (byte) 0xFF;
         encode[7] = (byte) 0xFF;
         Util.printHexString("encoded pin:", encode);
         return encode;
     }

     
     private byte[] getHAccno(String accno) {
         //取出主帐号;
         int len = accno.length();
         byte arrTemp[] = accno.substring(len < 13 ? 0 : len - 13, len - 1).getBytes();
         byte arrAccno[] = new byte[12];
         for (int i = 0; i < 12; i++) {
           arrAccno[i] = (i <= arrTemp.length ? arrTemp[i] : (byte) 0x00);
         }
         byte encode[] = new byte[8];
         encode[0] = (byte) 0x00;
         encode[1] = (byte) 0x00;
         encode[2] = (byte) Util.uniteBytes(arrAccno[0], arrAccno[1]);
         encode[3] = (byte) Util.uniteBytes(arrAccno[2], arrAccno[3]);
         encode[4] = (byte) Util.uniteBytes(arrAccno[4], arrAccno[5]);
         encode[5] = (byte) Util.uniteBytes(arrAccno[6], arrAccno[7]);
         encode[6] = (byte) Util.uniteBytes(arrAccno[8], arrAccno[9]);
         encode[7] = (byte) Util.uniteBytes(arrAccno[10], arrAccno[11]);
         Util.printHexString("encoded accno:", encode);
         return encode;
     }

     
    }

    test.java(测试类)

    package CodeApe;

    public class test {

     private static ANSIFormat pass;
     
     public static void main(String[] args) {
      // TODO Auto-generated method stub
      String pin = "123456";
      String accno = "123456789012345678";
      System.out.println("encoded pin:"+pin);
      System.out.println("encoded accno:"+accno);
      pass = new ANSIFormat(pin, accno);
      byte[] b = pass.process(pin, accno);
      
     }

    }

    效果图: - -!

    ANSI <wbr>X9.8标准 <wbr>PIN <wbr>xor <wbr>PAN获取PIN <wbr>BlOCK

  • 相关阅读:
    Redis3.0.1 Stable版本的集群部署(Mac)
    Maven的包依赖冲突可引发java.lang.IncompatibleClassChangeError错误
    Key/Value存储系统etcd的特性
    实时消息平台NSQ的特性
    StringIO函数
    对文件内容进行迭代
    基本文件方法
    打开文件
    正则表达式知识点汇总
    编译
  • 原文地址:https://www.cnblogs.com/hsapphire/p/6548782.html
Copyright © 2011-2022 走看看