从 nsdata 中的二进制数据流中提取数据
我现在是 Objective C 的新手,并试图解码我作为 NSdata 对象获得的数据流。
数据是 8 个字节长,例如:
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 不位于字节边界上?
我已经尝试过这样的操作:
NSUInteger len = [data length];
Byte *byteData = (Byte*)malloc(len);
memcpy(byteData, [data bytes], len);
但是无法使其在不同的边界下正常工作。如果这看起来有点含糊,我深表歉意,如果需要的话可以确认细节
I'm new to objective c at the moment and trying to decode a data stream that I'm getting as an NSdata object..
the data is 8 bytes long, eg:
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 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
From the nsdata array, how could i easily put out the different codes, considering that code3 doesnt sit on a byte boundary?
I've tried the likes of this:
NSUInteger len = [data length];
Byte *byteData = (Byte*)malloc(len);
memcpy(byteData, [data bytes], len);
however cannot make it work properly with the different boundaries.. Apologies if this seems a bit vague, can confirm details if need be
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
你正在做的事情看起来不错 - 有什么问题吗?您能否将数据放入 byteData 指针中?如果是这样,那么 Objective-C 或 C 或其他任何东西之间没有什么不同(并且 NSData 并不是一个真正好的标签) - 你只需要按位访问你的字节。
这可以通过创建具有像这样的位域定义的结构(伪代码,谷歌位域)
或者通过使用位掩码和/或使用移位来实现。
编辑回应评论:
这显示了如何进行移位
您将遇到的第一个问题是您从左到右显示您的位,这在小端系统上是不准确的,您需要将这些位视为:
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][3 位 b]
其中 a 和 b 是您关心的消息,“单独”获取这些消息的方法是:
这意味着,我希望使用 a 的前 5 位,并丢弃最低 3 位位,然后将所有内容右移 3 位以进行补偿。如果您开始于:
AAAAABBB,其中 A 是来自 a 的数据,B 是来自您不关心的 B 的数据,“x & 11111000b”将导致:
AAAAA000
以及随后的>> 3 将导致:
000AAAAA
其中 A 来自右移,在空白处引入 0,并丢弃右侧的 0。
因此,在这种情况下,要让 B 单独工作,您只需要做:
无需轮班。
如果您使用 2 个字节 N 和 M 跨位边界工作,例如:
NM
7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0
XXXXAAAAAAAXXXX
你会这样做:
我屏蔽掉,只从 N 和 M 中得到 A,然后我转移到结果位置。因此,当我按顺序完成这 3 个步骤时,合并的结果将是:
merged = 0 给出:
0 0 0 0 0 0 0 0
首先合并 |= 给出:
0 NNNN 0 0 0
第二个合并 |= 给出:
0 NNNNMMM
此时,您可以像平常一样对数据进行操作(转换为 int 或其他)
,就像我说的,替代方案是位字段
What you're doing looks fine - what's the issue? Are you able to get the data in to your byteData pointer? If so, then it's no different between objective-c or C or anything else (and NSData isn't really a good tag then) - you just need to access your bytes bitwise.
This could be achieved by creating a structure with bitfield definitions like this (pseudocode, google bitfield)
Or by using bitmasks and or by using shifts.
Edit in response to comment:
This shows how to do the shifting
First issue you're going to have is that you are showing your bits from left to right, which on little-endian systems is not accurate, you need to think about the bits as being:
7 6 5 4 3 2 1 0
Instead of
0 1 2 3 4 5 6 7
Otherwise you will never understand how the masking and shifting directions will work.
So assuming that you have bytes broken out, as you seem to, and you know what byte you're operating on, byte x :
7 6 5 4 3 2 1 0
[5 bits a][3 bits b]
Where a and b are messages you care about, the way to get these "alone" would be:
Which means, I want tto use those top 5 bits of a, and discard the lowest 3 bits, and then shift everything 3 bits to the right to compensate. If you started with:
AAAAABBB where A is data from a and B is data from B that you don't care about, the "x & 11111000b" will result in:
AAAAA000
And the subsequent >> 3 will result in:
000AAAAA
Where the A's come from right shifting, introducing 0's where the gaps were and discarding the 0's on the right.
So to get B alone in this case, you'd only have to do:
No shift necessary.
If you're working across bit boundaries with 2 bytes N and M such as:
N M
7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0
X X X X A A A A A A A X X X X X
You would do:
I'm masking out to only get A from N and M, and then I'm shifting to the RESULTING LOCATION. So that when I'm done with these 3 steps in order, the result on merged will be:
merged = 0 gives:
0 0 0 0 0 0 0 0
First merged |= gives:
0 N N N N 0 0 0
Second merged |= gives:
0 N N N N M M M
At this point, you act on your data as you normally would (cast to int or whatever)
And like I said, the alternative is bitfields