近端時間,領導提了一個需求留攒。說是微信中的發(fā)票管理下面帶有二維碼捌斧,通過掃描二維碼就可以開票,省去了每次開票都要仔細的核對發(fā)票信息的麻煩西土。
領導要求我們自己的app中發(fā)票管理盡量向微信靠攏讶舰。 通過查找資料,了解了制作發(fā)票二維碼的流程,特意在這里記錄一下跳昼。
1. 國稅局發(fā)布的制作二維碼規(guī)范
國家稅務總局辦公廳關于采用二維碼便捷納稅人開具增值稅發(fā)票有關事項的通知
2. 自己的理解
根據(jù)上面的規(guī)范般甲,明白需要把公司的信息(企業(yè)名稱,納稅人識別號鹅颊,注冊地址敷存,聯(lián)系電話,開戶行名稱堪伍,開戶行賬號)等字符串整合成一個字符串锚烦。
格式如下:起始符 + 版本號 + base64(企業(yè)名稱</>納稅人識別號</>注冊地址聯(lián)系電話</>開戶行名稱開戶行賬號</>CRC) + 結束符
- CRC是把(企業(yè)名稱</>納稅人識別號</>注冊地址聯(lián)系電話</>開戶行名稱開戶行賬號</>)括號中的字符串生成一個驗證碼
- base64是把(企業(yè)名稱</>納稅人識別號</>注冊地址聯(lián)系電話</>開戶行名稱開戶行賬號</>CRM驗證碼)這個字符串加密。
注意:開戶行名稱開戶行賬號 是在兩個</>之間的一個字符串杠娱,但是需要在開戶行名稱和開戶行賬號中間加一個“|”的英文符號挽牢。注冊地址聯(lián)系電話 也是需要在中間添加“|”谱煤。這個規(guī)范中沒寫摊求,但是必須添加的。不添加會在解析時當成一個字符串刘离,而不是顯示各自的信息室叉。
在線驗證網(wǎng)址:
3. 使用CRC驗證的經(jīng)驗
根據(jù)上面的規(guī)范硫惕,CRM驗證使用的是CRC-16算法茧痕,高位在前,低位在后恼除。在通過對比踪旷,發(fā)現(xiàn)CRC-16/CCITT- FALSE 和 CRC16_XMODEM兩個都滿足。所以我就選擇了使用CRC-16/CCITT- FALSE來生成驗證碼豁辉。
在IOS中我是使用的 喝小酒的網(wǎng)摘的文章中的C語言編寫的方法令野。大概代碼如下:
// 轉(zhuǎn)碼,返回的是unsigned short
unsigned short CRC16_CCITT_FALSE(unsigned char *puchMsg, unsigned int usDataLen)
{
unsigned short wCRCin = 0xFFFF;
unsigned short wCPoly = 0x1021;
unsigned char wChar = 0;
while (usDataLen--)
{
wChar = *(puchMsg++);
wCRCin ^= (wChar << 8);
for(int i = 0;i < 8;i++)
{
if(wCRCin & 0x8000)
wCRCin = (wCRCin << 1) ^ wCPoly;
else
wCRCin = wCRCin << 1;
}
}
return (wCRCin) ;
}
/// 需要把上面方法返回的unsign short 轉(zhuǎn)化為二進制類型
+ (NSString *)getBinaryByDecimal:(NSInteger)decimal {
NSString *binary = @"";
while (decimal) {
binary = [[NSString stringWithFormat:@"%ld", decimal % 2] stringByAppendingString:binary];
if (decimal / 2 < 1) {
break;
}
decimal = decimal / 2 ;
}
if (binary.length % 4 != 0) {
NSMutableString *mStr = [[NSMutableString alloc]init];;
for (int i = 0; i < 4 - binary.length % 4; i++) {
[mStr appendString:@"0"];
}
binary = [mStr stringByAppendingString:binary];
}
return binary;
}
調(diào)用方法:
+ (NSString *)stringCRC16_CCITT_FALSEWithData:(NSData *)data dataLength:(NSInteger)dataLength {
unsigned short wcrcin = CRC16_CCITT_FALSE((Byte *)[data bytes], (int)dataLength);
//十進制轉(zhuǎn)二進制
return [NSString getBinaryByDecimal:wcrcin];
}
4. base64加密徽级。
base64加密這個網(wǎng)上都有气破,并且也有第三方的文件,原理我也不太明白餐抢∠质梗可以自己去網(wǎng)上搜索,這個比較常見旷痕。
5. 完成效果
生成二維碼以后碳锈,需要使用微信公眾號上的《國稅發(fā)票助手》來驗證,切記別用微信自己的欺抗,剛開始就犯了這個錯誤殴胧,微信是自己開發(fā)的,只能用微信的格式來掃描分享。
6. 總結
需要注意如下:
開戶行名稱開戶行賬號 兩個信息中間一定要加“|”团滥。
CRC生成驗證時竿屹。我查資料JAVA使用的CRC-16驗證方法生成的二進制編碼跟C語言生成的不一樣。因為測試的時候在線測試使用JAVA生成的二進制可以用灸姊,就一直糾結為什么不一樣拱燃。不過使用C語言生成的通過測試也能用。