php 生成国税局二维码


可以看出,最最主要的就是计算这个 CRC 了,不过上面的这篇博文给出的代码不仅是 java 版本的,关键的是代码不完整,变量初值没给出来。这就很尴尬了。于是继续百度,发现 php 官网上有计算 crc16 的算法例子(点击打开链接),或直接见以下代码(我只拿了其中一份简洁的代码例子如下):


public class TestCrc  {  
  
    public static void main(String[] args){  
            
        String input = "北京国税123456789</>9XXxx123456789XXxx</>北京市通州区正在大厦123456789</>中国银行123456789</>";    
          
        try {  
              
            byte[] inputs = input.getBytes("GBK");    
            for (int i = 0; i < inputs.length; i ++) {    
                    div(inputs[i]);    
                }    
              byte r = 0;    
                div(r);    
                div(r);   
                String crc3=Integer.toHexString(a);  
                  
            System.out.println(Integer.toHexString(a));  
          
          String jm=getBase64(input+crc3.toUpperCase());//base64加密  
          String s="$01"+jm+"$";  
           
          String a="5YyX5Lqs5Zu956iOMTIzNDU2Nzg5PC8+OVhYeHgxMjM0NTY3ODlYWHh4PC8+5YyX5Lqs5biC6YCa5bee5Yy65q2j5Zyo5aSn5Y6mMTIzNDU2Nzg5PC8+5Lit5Zu96ZO26KGMMTIzNDU2Nzg5PC8+MjAxQQ==";  
          System.out.println(s);  
          String jmh1=getFromBase64(a);  
          System.out.println(jmh1);  
            
          
        } catch (Exception e) {  
              
            e.printStackTrace();  
        }    
    }  
      
        static int a=0x0000;  
        static int crc16=0x8005;  
      
    private static void div(byte input) {//算法   
        int temp=0;    
          
        int data = input;    
        for (int i = 0; i < 8; i ++) {    
            temp = a & 0x8000;    
            a = a << 1;    
            a = a & 0x0000ffff;    
           int numIn = data & 0x80;    
           numIn = numIn >> 7;    
           a = a ^ numIn;    
           if (temp == 0x8000) {    
               a = a ^ crc16;    
           }    
           data = data << 1;    
           a = a & 0x0000ffff ;   
        }   
    }  
      
    public static String getBase64(String str) {  //加密  
        byte[] b = null;    
        String s = null;    
        try {    
            b = str.getBytes("utf-8");    
        } catch (UnsupportedEncodingException e) {    
            e.printStackTrace();    
        }    
        if (b != null) {    
            s = new BASE64Encoder().encode(b);    
        }    
        return s;    
    }   
      
      
    public static String getFromBase64(String s) {  //解密  
        byte[] b = null;    
        String result = null;    
        if (s != null) {    
            BASE64Decoder decoder = new BASE64Decoder();    
            try {    
                b = decoder.decodeBuffer(s);    
                result = new String(b, "utf-8");    
            } catch (Exception e) {    
                e.printStackTrace();    
            }    
        }    
        return result;    
    }     
} 


转化php代码


class TestCrc  {  
    public static function getBytes($string) {/* 获取字节流数组(ASCII码) */  
        $bytes = array();   
        for($i = 0; $i < strlen($string); $i++){   
             $bytes[] = ord($string[$i]);   
        }   
        return $bytes;   
    }  
    public static function test($input){/* 传递参数为填写在国税发票助手的内容拼成的二维码存储内容格式,返回的是存入二维码的内容 */  
	$inputs = iconv('utf-8', 'gbk', $input);  
        $inputs = array_map('ord', str_split($inputs));  
        for ($i = 0; $i < count($inputs); $i++) {    
                self::div($inputs[$i]);    
        }  
          $r = 0;  
          self::div($r);  
          self::div($r);  
          $crc = sprintf("%04X",self::$a); /* 输出4位16进制数(不足四位用0占位) */  
    	$QRcodeContent = $input.$crc;  
    	return '$01'.base64_encode($QRcodeContent).'$';  
    }  
    public static $a=0x0000;  
    public static $crc16=0x8005;   
    private static function div($input) {/* 算法 */  
        $temp=0;    
        $data = $input;    
        for ($i = 0; $i < 8; $i ++) {    
        $temp = self::$a & 0x8000;    
        self::$a = self::$a << 1;    
        self::$a = self::$a & 0x0000ffff;    
       $numIn = $data & 0x80;    
       $numIn = $numIn >> 7;    
       self::$a = self::$a ^ $numIn;    
       if ($temp == 0x8000) {    
           self::$a = self::$a ^ self::$crc16;    
       }  
       $data = $data << 1;    
       self::$a = self::$a & 0x0000ffff ;   
    }   
}  

测试代码:


$content = "广东xx网络有限公司</>91442000***3</>中山市石岐区xxx 0760-88888888</>中国建设银行中山兴中道支行 4400***0</>";     
Content = TestCrc::test($content); 

结果发现结果还是与税局发票助手的生成的 crc16 结果不一样,后来一想直接不要将输入的内容转 gbk 格式试试看,结果就可以了,主要将上述代码修改如下:

修改 test 函数的前两行代码为:

[php]  view plain  co
  1. $inputs = self::getBytes($input);
即可顺利生成与税局发票助手一致的二维码了(存储的 base64 内容一致)。快去试试吧!

感觉很多东西一开始很陌生,会有种惧怕的感觉,但是一旦尝试深入解决,只要坚持,我相信大部分(不可能是全部)难题都可以被你解决的!



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值