zoukankan      html  css  js  c++  java
  • ios 条形码、二维码读取相关

    ios 条形码、二维码读取相关

    目的只是要做一个能随时随地进行条形码扫描,并和某单号配对的小工具。

    在淘宝上看了一下扫描枪的价格,便宜的,只能插在电脑上使用,这个不符合随时随地的条件。贵的,有显示屏,可编程,但是目前投入回报比太小,不值得付出。

    怎么办呢?手上有一台 Mac Mini ,有一台 iPhone, 看过两个月的 ObjC 的基本语法和 ios 开发教程,不如就写个 app 吧。

    一,越狱

    首先,iphone 要越狱,网上大把,就不说了。

    二,免证书真机调试

    对于我这种初学者,花几百RMB去弄个开发者账号,然后真机调试,实在是浪费。但是条形码扫描又必须真机调试(摄像头无法模拟),所以,破解一下 Xcode ,弄免证书真机调式是必经之路:

    http://kqwd.blog.163.com/blog/static/4122344820117191351263/

    这遍博文写的很详细,各个主流版本的 Xcode 的都有讲,仔细对着做就成。当然iphone 必须先越狱。

    三,ZBar

    目前 ios 上有开源的扫描库 ZXing 和 ZBar, 我没有比较,对着网上搜到的博文就用了 ZBar,过程还算顺利。

    但是如果有一堆条形码摆在那里,ZBar 的对焦框会飘来飘去。

    ZBar 有个 scanCrop 属性,默认值是 (0,0,1,1)代表全屏,

    the region of the image that will be scanned.  normalized coordinates.

    这句注释看起来很费解。normalized coordinates 我不明白到底是什么意思。

    在屏幕上画一个框,这个框代表可扫描区域,然后把这个区域的 CGRect 传给 scanCrop 显然是不能工作的。

    几经周折,找到了如下解决方法:

    View Code
    1 -(CGRect)getScanCrop:(CGRect)rect readerViewBounds:(CGRect)rvBounds{
    2     CGFloat x,y,width,height;
    3     x = rect.origin.y / rvBounds.size.height;
    4     y = 1 - (rect.origin.x + rect.size.width) / rvBounds.size.width;
    5     width = (rect.origin.y + rect.size.height) / rvBounds.size.height;
    6     height = 1 - rect.origin.x / rvBounds.size.width;
    7     return CGRectMake(x, y, width, height);
    8 }

    很奇怪,x,y,width,height 好像都是翻的,不过,这个确实是可用的。

        self.readerView.scanCrop = [self getScanCrop:maskView.frame readerViewBounds:self.readerView.bounds];

    四,对二维码加、解密

    除了条形码,还有另外一个码需要扫描,并和条形码对应。这个码里还要附加一些另外信息,所以,我就用了二维码。

    生成二维码,我用的是 ZXing.NET, 在 NuGet 里可以找到,这个没什么难度。

    因为这要生成二维码的内容,涉及到隐私,不是随便拿个手机就可以扫扫的。所以,我用了AES加密。

    在.NET里做AES加密是很简单的事情,但是在 ios 里做解密,对我来说,有些复杂。

    因为加密后的内容可能为不能显示的字符,所以需要用 Base64 转一下。

    网上提供的一些 Base64 代码不是缺胳膊就是少腿,用着非常虐人。用了GTM后,赶脚爽多了

    http://google-toolbox-for-mac.googlecode.com/svn/trunk/

    需要FQ,FQ我用GoAgent

    提供一下 ios 下的AES加解密代码:

    View Code
     1 #import <CommonCrypto/CommonCryptor.h>
     2 #import "AESCrypt.h"
     3 #import "GTMDefines.h"
     4 #import "GTMBase64.h"
     5 
     6 @implementation AESCrypt
     7 
     8 
     9 
    10 +(NSString*) dencryptData:(NSString*)str key:(NSString *)key{
    11     NSString *newKey = [key stringByPaddingToLength:32 withString:@"0" startingAtIndex:0 ];
    12     NSString *iv = [key stringByPaddingToLength:16 withString:@"0" startingAtIndex:0];
    13     
    14     NSData *data = [GTMBase64 decodeString:str];
    15     NSData *keyData = [newKey dataUsingEncoding:NSUTF8StringEncoding];
    16     NSData *ivData = [iv dataUsingEncoding:NSUTF8StringEncoding];
    17     
    18     NSData *result = [self dencryptData:data :keyData :ivData];
    19     
    20     return [[NSString alloc ] initWithData:result encoding:NSUTF8StringEncoding ];
    21 }
    22 
    23 + (NSData*)dencryptData:(NSData*)data :(NSData*)key :(NSData*)iv
    24 {
    25     size_t bufferSize = [data length] + kCCBlockSizeAES128;
    26     void *buffer = malloc(bufferSize);
    27     size_t encryptedSize = 0;
    28     CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt,
    29                                           kCCAlgorithmAES128,
    30                                           kCCOptionPKCS7Padding,
    31                                           [key bytes],
    32                                           [key length],
    33                                           [iv bytes],
    34                                           [data bytes],
    35                                           [data length],
    36                                           buffer,
    37                                           bufferSize,
    38                                           &encryptedSize);
    39     if (cryptStatus == kCCSuccess)
    40         return [NSData dataWithBytesNoCopy:buffer length:encryptedSize];
    41     else
    42         free(buffer);
    43     
    44     return NULL;
    45 }
    46 
    47 
    48 
    49 
    50 
    51 +(NSString *)encrypt:(NSString *)str key:(NSString *)key{
    52     NSString *newKey = [key stringByPaddingToLength:32 withString:@"0" startingAtIndex:0 ];
    53     NSString *iv = [key stringByPaddingToLength:16 withString:@"0" startingAtIndex:0];
    54     
    55     NSData *data = [str dataUsingEncoding:NSUTF8StringEncoding];
    56     NSData *keyData = [newKey dataUsingEncoding:NSUTF8StringEncoding];
    57     NSData *ivData = [iv dataUsingEncoding:NSUTF8StringEncoding];
    58     
    59     NSData *result = [self encryptData:data key:keyData iv:ivData];
    60     result = [GTMBase64 encodeData:result];
    61     
    62     return [[NSString alloc] initWithData:result encoding:NSUTF8StringEncoding ];
    63 }
    64 
    65 + (NSData*)encryptData:(NSData*)data key:(NSData*)key iv:(NSData*)iv
    66 {
    67     size_t bufferSize = [data length] + kCCBlockSizeAES128;
    68     void *buffer = malloc(bufferSize);
    69     size_t encryptedSize = 0;
    70     CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt,
    71                                           kCCAlgorithmAES128,
    72                                           kCCOptionPKCS7Padding,
    73                                           [key bytes],
    74                                           [key length],
    75                                           [iv bytes],
    76                                           [data bytes],
    77                                           [data length],
    78                                           buffer,
    79                                           bufferSize,
    80                                           &encryptedSize);
    81     if (cryptStatus == kCCSuccess)
    82         return [NSData dataWithBytesNoCopy:buffer length:encryptedSize];
    83     else
    84         free(buffer);
    85     
    86     return NULL;
    87 }
    88 
    89 @end

    需要注意的是:IV 是 取KEY的前16个字符,不足的在后面补0,KEY取原KEY的前32个字符,不足的,在后面补0。

    还有 PKCS7。要保证.NET里的和ios里的对应参数一至。

    五,ARC

    GTM 提供的代码有很多 retain,autorelease 等,对于ARC这些是不行的。一开始,我简单的把 autorelease 删了,但是 retain 不知道要怎么处理了。后来搜了一下:

    在工程的 Build Phases -> Compile Sources 下选中不使用ARC的代码,双击,输入:-fno-objc-arc ,就可以了。

     
     
     
    标签: ioszbarAES
  • 相关阅读:
    转 Python学习(九)
    转 Python学习(八)
    转 Python学习(七)
    转 Python学习(六)
    转 Python学习(五)
    转 Python学习(四)
    转Python学习(三)
    转Python学习(一)
    面向对象第三章(向上造型、重写、重载)
    面向对象第一章(成员变量、局部变量、重载)
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/2973891.html
Copyright © 2011-2022 走看看