好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

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

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 ,就可以了。

 

 

 

标签:  ios ,  zbar ,  AES

作者: Leo_wl

    

出处: http://www.cnblogs.com/Leo_wl/

    

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

版权信息

查看更多关于ios 条形码、二维码读取相关的详细内容...

  阅读:45次