首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >从nsdata中的二进制数据流中提取数据

从nsdata中的二进制数据流中提取数据
EN

Stack Overflow用户
提问于 2011-04-15 22:03:41
回答 1查看 1.7K关注 0票数 1

目前,我是objective c的新手,正在尝试解码作为NSdata对象获得的数据流。

数据长度为8字节长,例如:

代码语言:javascript
复制
 1               2               3               4               
 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|  code1        |code2  |   code3               | code4         |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

 5               6               7               8              
 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                           code5                                |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

在nsdata数组中,考虑到code3不是位于字节边界上,我该如何轻松地输出不同的代码呢?

我尝试过这样的方法:

代码语言:javascript
复制
NSUInteger len = [data length];
Byte *byteData = (Byte*)malloc(len);
memcpy(byteData, [data bytes], len);

然而,不能使它在不同的边界下正常工作。抱歉,如果这看起来有点含糊,如果需要,可以确认细节

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2011-04-15 22:09:13

你所做的看起来很好--有什么问题吗?你能把数据放到你的byteData指针里吗?如果是这样,那么在objective-c或C或其他任何东西之间没有什么不同(而且NSData也不是一个很好的标记)-你只需要按位访问你的字节即可。

这可以通过创建一个具有如下位域定义的结构来实现(伪代码,google位域)

代码语言:javascript
复制
struct 
{
 char byte1;
 char a3bitfield : 3;
 char a5bitfield : 5;
 char byte3;
}

或者通过使用位掩码和/或通过使用移位。

响应评论进行编辑:

This shows how to do the shifting

你会遇到的第一个问题是,你从左到右显示你的比特,这在小端系统上是不准确的,你需要考虑比特是:

7 6 5 4 3 2 1 0

而不是

0 1 2 3 4 5 6 7

否则,您将永远不会理解掩码和移动方向是如何工作的。

因此,假设您有字节被分解,就像您看起来那样,并且您知道您正在操作哪个字节,字节x:

7 6 5 4 3 2 1 0 5位a

其中a和b是您关心的消息,获取这两个“单独”消息的方法是:

代码语言:javascript
复制
char onlya = ((x & 11111000b) >> 3);

这意味着,我希望使用a的前5位,并丢弃最低的3位,然后将所有3位向右移位以进行补偿。如果您从: AAAAABBB开始,其中A是来自a的数据,B是您不关心的来自B的数据,则"x & 11111000b“将导致: AAAAA000,随后的>> 3将导致: 000AAAAA

其中A来自右移位,在间隙所在的地方引入0,并在右侧丢弃0。

因此,要在这种情况下单独获取B,您只需执行以下操作:

代码语言:javascript
复制
char onlyb = (x & 00000111b);

不需要换班。

如果您正在使用2个字节N和M的位边界工作,例如:

N M 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 X A A X X

你会这样做:

代码语言:javascript
复制
char merged = 0;
merged |= (N & 00001111b) << 3;
merged |= (M & 11100000b) >> 5;

我只从N和M中得到A,然后我转移到结果位置。因此,当我按顺序完成这3个步骤时,合并后的结果将是:

合并=0给出:0 0 0

第一个合并的|=给出:0 N 0 0 0

第二个合并的|=给出:0 N M M M

此时,您可以像往常一样对数据执行操作(转换为int或其他类型)

就像我说的,另一种选择是位域

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5677915

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档