将UTF8编码的3字节中英文转成2字节中英文.
1. 首先要考虑将String转成一个bytes的数组, 每个汉字是3个bytes, 英文或者标点是1个byte.
2. 然后去判断一下每一个byte的前面几个bit, 看下面的表, 1个byte的字符, 就是英文跟标点, 它的第1个bit是0;
3. 重点是3个bytes的字符, 就是汉字, 或者说CJK, 它的第1个byte的前面4个bit, 是1110, 那么我们可以根据这个来判断.看起来好像下面的代码, 居然是java跟oc可以共用的 :)
if((bytes[i]>>4)==0x0E){
highPos=(bytes[i]<<4)|((bytes[i+1]&0x3f)>>2);
lowPos=((bytes[i+1]&0x03)<<6)|(bytes[i+2]&0x3f);
//NSLog(@"highPos: %x lowPos: %x",highPos,lowPos);
chnCodeArray[chnCodeIndex]=highPos;
chnCodeArray[chnCodeIndex+1]=lowPos;
chnCodeIndex=chnCodeIndex+2;
i=i+3;
}else if(bytes[i]>>7==0){
chnCodeArray[chnCodeIndex]=0;
chnCodeArray[chnCodeIndex+1]=bytes[i];
chnCodeIndex=chnCodeIndex+2;
i++;
}
chnCodeArray就是用来存放结果的byte的数组.
4. 根据协议包, 先发送字符串开始, 数据, 结束的数据包.
[self sendPackage:UTF8_CODE_TRANS_START_CMD withCmdNumber:number withLength:length];
[self sendUTF8Data:utf8Bytes];
[self sendPackage:UTF8_CODE_TRANS_END_CMD withCmdNumber:number withLength:length];
可以看得出, 分别发送cmdPackage跟dataPackage, 可以写得更好的, 希望在安卓的版本中有更好的设计方法.
5. 简单看一下, sendPackage这个方法:
for(int i=0;i<3;i++){
UInt64 startTime=[[NSDate date] timeIntervalSince1970]*1000;
if(packageType==UTF8_CODE_TRANS_START_CMD){
_packageID=[self sendUTF8TransStartCMDPackage:cmdNumber withLength:length];
}else if(packageType==UTF8_CODE_TRANS_END_CMD){
_packageID=[self sendUTF8TransEndCMDPackage:cmdNumber withLength:length];
}
if([self waitForACK:startTime]){
return;
}
}
重试3次, 如果有ACK就算发送成功.
-(bool)waitForACK:(UInt64) startTime{
[self readFFF1Value];
while(_ack==0){
UInt64 endTime=[[NSDate date] timeIntervalSince1970]*1000;
if((endTime-startTime)>1000){
NSLog(@"Over time");
return 0;
}
if(_ack==1){
//NSLog(@"ack==1");
return 1;
}
}
return 0;
}
sendUTF8TransStartCMDPackage方法的精髓是, 妈的, 自己看吧:
_packageSendingType.packageType=UTF8_CODE_TRANS_START_CMD;
_packageSendingType.warningCode=cmdNumber;
_packageSendingType.packageLength=length;
int packageID=arc4random()%255;
NSData *data=[_blePackageFactory createPackage:_packageSendingType withPackageID:packageID];
[self writeCharFFF1:data];
_ack=0;
return packageID;
这里会返回一个随机产生的packageID, 因为app校验ack的时候, 要用到这个packageID.
-(void) checkACK:(NSData*)charValue{
Byte byteBuffer[20];
//NSLog(@"checkACK thread is: %@",[NSThread currentThread]);
//NSLog(@"%d",(int)[notifObj length]);
[charValue getBytes:byteBuffer length:20];
if((byteBuffer[3]==_packageID)&&(byteBuffer[4]==TYPE_DATA_ACK)&&(byteBuffer[5]==ACK_YES)){
_ack=1;
NSLog(@"ACK check ok");
_transferErrorCount=0;
[[NSNotificationCenter defaultCenter] postNotificationName:@"BLECharValue" object:@"ACK!"];
}else{
_transferErrorCount++;
if(_transferErrorCount>5){
_transferErrorCount=0;
[[NSNotificationCenter defaultCenter] postNotificationName:@"BLECharValue" object:@"传输错误"];
}else{
//[self sendStartPackage];
[self resendPackage];
}
}
}
这个方法是在读取char值的回调中运行的, 所以用上了一个外部的全局变量, 叫_ack
6. 总结一下, 配合之前规定的通讯协议, 这个蓝牙通讯, 无非两种包, 一种是命令包, 即通讯开始, 通讯结束, 一种是数据的传输.
关键是中间有很多信息, 例如, 包ID, 校验码, 字符串编号, 开始位, 停止位, 诸如此类...
将UTF8编码的3字节中英文转成2字节中英文.的更多相关文章
- 【异常记录(六)】vs文件乱码:文件加载,使用Unicode(UTF-8)编码加载文件xxx时,有些字节已用Unicode替换字符替换。保存该文件将不会保留原始文件内容。
VS2013偶遇这种情况,页面汉字编码出现乱码. .... 按照网上查到的: 工具>选项>文本编辑器> 勾选了 然并卵,还是乱码... 其实炒鸡简单 用记事本打开另存为,选择 ...
- 如何将一个用utf-8编码的文本用java程序转换成ANSI编码的文本
jdk有一个关于UTF-8的bug所以加了一句 br.skip(1); bugID: http://bugs.java.com/view_bug.do?bug_id=4508058 public st ...
- Java不同编码方式,中英文字符所占字节数
测试代码 public class Test { public static void main(String[] args){ String[] charsetNames={ "UTF-8 ...
- 【Java】如何检测、替换4个字节的utf-8编码(此范围编码包含emoji表情)
> 参考的优秀文章 1.十分钟搞清字符集和字符编码 2.Java中byte与16进制字符串的互相转换 3.[异常处理]Incorrect string value: '\xF0\x90\x8D\ ...
- 在 Perl看来, 字符串只有两种形式. 一种是octets, 即8位序列, 也就是我们通常说的字节数组. 另一种utf8编码的字符串, perl管它叫string. 也就是说: Perl只熟悉两种编
在 Perl看来, 字符串只有两种形式. 一种是octets, 即8位序列, 也就是我们通常说的字节数组. 另一种utf8编码的字符串, perl管它叫string. 也就是说: Perl只熟悉两种编 ...
- python中文utf8编码后是占3个字符,unicode汉字为2字节
一个中文utf8编码后是占3个字符,所以求长度的函数可以这样写 def str_len(str): try: row_l=len(str) utf8_l=len(str.encode('utf-8') ...
- 刨根究底字符编码之十一——UTF-8编码方式与字节序标记
UTF-8编码方式与字节序标记 一.UTF-8编码方式 1. 接下来将分别介绍Unicode字符集的三种编码方式:UTF-8.UTF-16.UTF-32.这里先介绍应用最为广泛的UTF-8. 为满足基 ...
- 1个汉字在UTF-8编码占3个字节
http://blog.csdn.net/ns_code/article/details/14162087 http://www.ruanyifeng.com/blog/2007/10/ascii_u ...
- ASCII、Unicode和UTF-8编码的区别;中英文混合截取
ASCII编码是128个字符 中国把汉字编入GB2312,Shift_JIS/Euc-kr各国标准..... Unicode是为了解决各国乱码的,但浪费存储空间 UTF-8编码把一个Unicode字符 ...
随机推荐
- 微信小程序:开发之前要知道的三件事
前言 微信之父张小龙在年初的那次演讲中曾表示:"我自己是很多年的程序员,我觉得我们应该为开发的团队做一些事情".几个月后,微信正式推出微信应用号(即微信小程序),在互联网中掀起了又 ...
- 微信支付开发(11) Native支付
关键字:微信公众平台 微信支付 Native原生支付作者:方倍工作室原文:http://www.cnblogs.com/txw1958/p/wxpay-native.html 由于微信支付接口更新,本 ...
- ■ apache隐藏、混淆php后缀名的几种方法
经常看见有些网站www.***.com/kkk或者www.***.com/kkk.jsp这样访问,其实kkk可能是个php脚本文件,被隐藏了或者混淆了.php后缀,这样至少不会让别人一眼看出网站是ph ...
- python之map、filter、reduce、lambda函数
map map函数根据提供的函数对指定的序列做映射,定义:map(function, sequence[,sequence,...])--->list 例1 >>> map(l ...
- MagicNotes:自我管理中的破窗效应
MagicNotes,思绪随风飞扬,偶尔在这里停留. 在<程序员修炼之道——从小工到专家>这本书里,有这么一段描述: 在市区,有些建筑漂亮而整洁,而另一些却是破败不堪的“废弃船只”.为什么 ...
- NLS_LANG参数说明
NLS_LANG参数说明 格式: NLS_LANG = language_territory.charset 它有三个组成部分(语言.地域和字符集),每个成分控制了NLS子集的特性.其中: Lang ...
- java mock
一篇文章: 5分钟了解Mockito 一.什么是mock测试,什么是mock对象? 先来看看下面这个示例: 从上图可以看出如果我们要对A进行测试,那么就要先把整个依赖树构建出来,也就是BCDE的实例. ...
- jquery获取自身元素的html
在开发过程中,jQuery.html() 是获取当前节点下的html代码,并不包含当前节点本身的代码,然而我们有时候的确需要,可以通过jQuery.prop("outerHTML" ...
- 算法提高 c++_ch02_01
http://lx.lanqiao.org/problem.page?gpid=T237 算法提高 c++_ch02_01 时间限制:1.0s 内存限制:512.0MB 编写一个程 ...
- [原创]java WEB学习笔记75:Struts2 学习之路-- 总结 和 目录
本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...