您的位置:程序门 -> .net技术 -> c#



从byte[]中提取特定数据。在线求助!急啊


[收藏此页] [打印本页]选择字色:背景色:字体:[][][]


从byte[]中提取特定数据。在线求助!急啊[已结贴,结贴人:maybehelios]
发表于:2007-03-24 21:42:41 楼主
有一个数组,长度不定。数组中内容如下格式
byte[]   data   =   new   byte[]   {   ......0xf2,   0x7d,   0xf2,   0x7d,1,2,3,4,5,6,7,8,9,0,......,0xeb,   0xb7,   0xeb,   0xb7,0xf2,   0x7d,   0xf2,   0x7d,32,23,43,54,......0xeb,   0xb7,   0xeb,   0xb7,0xf2,   0x7d,   0xf2,   0x7d,12,12,23,32,31,......};

其中data   的长度不固定,......表示不定长数据。
要求得到
夹在   0xf2,   0x7d,   0xf2,   0x7d,和0xeb,   0xb7,   0xeb,   0xb7
中间的所有数组
请大家给个思路
有高效源代码的俺使劲给分。
这个100分明显太少了,问题一旦解决,还可以另开一个加分贴。
发表于:2007-03-24 21:44:141楼 得分:0
怎么列表中看不到
急啊
发表于:2007-03-24 21:51:232楼 得分:0
up
请大家多多指点阿

最好将所有数组放在一个
byte[][]中一次返回
发表于:2007-03-24 21:55:373楼 得分:0
说一下背景阿
就是在tcp客户端接收数据的时候,经常一次endreceive收到对方发送的连接起来的几帧。上面的  
.0xf2,   0x7d,   0xf2,   0x7d是帧头,0xeb,   0xb7,   0xeb,   0xb7是帧尾


求求大家拉
发表于:2007-03-24 22:21:394楼 得分:95
好久没做算法了,随手写一个。


list <byte[]>   list   =   new   list <byte[]> ();

int   flag   =   0;
int   index   =   0;
list <byte>   section   =   new   list <byte> ();

foreach   (   byte   b   in   data   )
{
    if   (   b   ==   (byte)   0xf2   &&   (flag   ==   0   ¦ ¦   flag   ==   2)   )
        flag++;
    else
        flag   =   0;

    if   (   b   ==   (byte)   0x7d   &&   (flag   ==   1   ¦ ¦   flag   ==   3)   )
        flag++;
    else
        flag   =   0;
    if   (   flag   ==   4   )
    {
        flag   =   5;
        continue;
    }

    if   (   flag   >   4   )
        section.add(   byte   );
    if   (   b   ==   (byte)   0xeb   &&   (   flag   ==   5   ¦ ¦   flag   ==   7   )
        flag++;
    else
        flag   =   5;

    if   (   b   ==   (byte)   0xb7   &&   (   flag   ==   6   ¦ ¦   flag   ==   8   )
        flag++;
    else
        flag   =   5;

    if   (   flag   ==   9   )
    {
        section.removerange(   section.lenth   -   4,   4   );
        list.add(   section.toarray()   );
    }
}
发表于:2007-03-24 22:22:075楼 得分:0
list <byte[]>   list   =   new   list <byte[]> ();

int   flag   =   0;
int   index   =   0;
list <byte>   section   =   new   list <byte> ();

foreach   (   byte   b   in   data   )
{
    if   (   b   ==   (byte)   0xf2   &&   (flag   ==   0   ¦ ¦   flag   ==   2)   )
        flag++;
    else
        flag   =   0;

    if   (   b   ==   (byte)   0x7d   &&   (flag   ==   1   ¦ ¦   flag   ==   3)   )
        flag++;
    else
        flag   =   0;
    if   (   flag   ==   4   )
    {
        flag   =   5;
        continue;
    }

    if   (   flag   >   4   )
        section.add(   byte   );
    if   (   b   ==   (byte)   0xeb   &&   (   flag   ==   5   ¦ ¦   flag   ==   7   )
        flag++;
    else
        flag   =   5;

    if   (   b   ==   (byte)   0xb7   &&   (   flag   ==   6   ¦ ¦   flag   ==   8   )
        flag++;
    else
        flag   =   5;

    if   (   flag   ==   9   )
    {
        section.removerange(   section.lenth   -   4,   4   );
        list.add(   section.toarray()   );
        flag   =   0;
    }
}
发表于:2007-03-24 22:23:286楼 得分:0
最后一段改为
    if   (   flag   ==   9   )
    {
        section.removerange(   section.lenth   -   4,   4   );
        list.add(   section.toarray()   );
        flag   =   0;
        section   =   new   list <byte> ();
    }
发表于:2007-03-24 22:23:407楼 得分:0
未测试……
发表于:2007-03-24 22:33:508楼 得分:0
学习
我尝试一下
谢谢先

我刚试了一个方法,有点头绪,但是后面几个数组   就不对了。刚弄得
不知道大哥能不能帮忙给看看。谢谢

                static   byte[][]   func1(byte[]   rawbuffer,byte[]   head,byte[]trail)
                {
                        int   headcount   =0;
                        int   trailcount   =   0;
                        int   count   =   0;

                        byte[][]   buffer   =   new   byte[rawbuffer.length   /9][];//8+1(至少帧头4   数据1   帧尾4)

                                for   (int   jishu   =   0;   jishu   <   buffer.length;   jishu++)
                                {
                                        for   (;   count   <   rawbuffer.length;   count++)
                                        {
                                                if   ((rawbuffer[count]   ==   head[0])   &&   (rawbuffer[count   +   1]   ==   head[1])
                                                        &&   (rawbuffer[count   +   2]   ==   head[2])   &&   (rawbuffer[count   +   3]   ==   head[3]))
                                                {
                                                        headcount   =   count;
                                                        break;
                                                }
                                        }

                                        for   (count   =   headcount;   count   <   rawbuffer.length;   count++)
                                        {
                                                if   ((rawbuffer[count]   ==   trail[0])   &&   (rawbuffer[count   +   1]   ==   trail[1])
                                                        &&   (rawbuffer[count   +   2]   ==   trail[2])   &&   (rawbuffer[count   +   3]   ==   trail[3]))
                                                {
                                                        trailcount   =   count;
                                                        break;
                                                }
                                        }
                                        if   ((trailcount   -   headcount)   >   4)
                                        {
                                                buffer[jishu]   =   new   byte[trailcount   -   headcount   -   4];
                                                array.copy(rawbuffer,   headcount+4,   buffer[jishu],   0,   trailcount   -   headcount   -   4);
                                        }

                                }

                        return   buffer;
                }
发表于:2007-03-24 22:36:179楼 得分:0
试一下总是好的,试都不试就没机会搞懂了,我先看看……
发表于:2007-03-24 22:40:2710楼 得分:0
if   (   flag   >   4   )
section.add(   byte   );
if   (   b   ==   (byte)   0xeb   &&   (   flag   ==   5   ¦ ¦   flag   ==   7   )
flag++;
else
flag   =   5;

这个第二句,还得再请教一下
确实很急的。
能否加我qq,传个cs文件看看。谢谢qq:32304328

发表于:2007-03-24 22:42:4511楼 得分:0
section.add?

list是一个可变长数组,这里实际上就是将数据推入一个可变长数组,这个数组就叫section
发表于:2007-03-24 22:43:5112楼 得分:5
提供下我的思路

.0xf2,   0x7d,   0xf2,   0x7d是帧头,0xeb,   0xb7,   0xeb,   0xb7是帧尾
先匹配帧头   从帧头开始记录   直到碰到第一个帧尾   剪除固定长度的头帧尾   就得到要的数据了;

严格来说   帧头→帧尾才是一个有意义的信息段   帧头→帧头、帧尾   →帧尾   、帧尾→帧头都应该是丢失了帧   应该抛弃   具体要看你们的处理机制


性能   主要是在匹配的算法上   算法好   速度就快     帧头帧尾是固定长度   只要能快速匹配出有意义的信息段   减去固定的帧   就能得到数据。
关键还是匹配的算法上   可以多实验几种算法,看哪种方法快
发表于:2007-03-24 22:48:4213楼 得分:0
其实我的程序是一个非常典型的有限状态机。

其中flag就是状态。

看懂了flag就明白她的工作原理了。

flag含义:

0、未知数据
1、已匹配标头的第一位
2、已匹配标头的第二位
3、已匹配标头的第三位
4、已匹配标头的第四位
5、已进入数据段,开始匹配数据。
6、已匹配标尾的第一位
7、已匹配标尾的第二位
8、已匹配标尾的第三位
9、已匹配标尾的第四位
发表于:2007-03-24 22:50:0714楼 得分:0
section.add(   byte   );
这里的byte是??
感觉自己着急的不行,静不下心来看
发表于:2007-03-24 22:52:3815楼 得分:0
所以程序的逻辑就是,如果状态为0,而遇到了帧头第一位的话,就只状态1
而在状态1-4的时候,遇到任何不符合帧头的数据,就重来,状态置0。

不过这里好像也有些问题。因为如果遇到0xf2,0xf2,0x7d,0xf2,0x7d的数据就会有问题,我再改改。

后面帧头判断同样的道理

因为这个是只向前读的,所以应该说效率是最好的。
发表于:2007-03-24 22:53:0216楼 得分:0
section.add(   byte   );
这里的byte是??
感觉自己着急的不行,静不下心来看


写错了,section.add(   b   );
发表于:2007-03-24 22:54:4517楼 得分:0
你的这个问题其实很复杂,如果静不下心来其实找不到好解法,当然如果转换成字符串然后用正则表达式当然最简单,如果你真的是那么急,不妨试试,但不能用encoding,而应该自己想办法,因为encoding是不能保证转换成字符串还能转换回来的。
发表于:2007-03-24 22:56:0418楼 得分:0
我写一个可行的你自己慢慢研究吧,原理我已经说过了。
发表于:2007-03-24 22:57:5119楼 得分:0
真是麻烦了
明天就要测试了。这里还没搞定
发表于:2007-03-24 22:59:5420楼 得分:0
又一个加班的   郁闷
发表于:2007-03-24 23:02:5821楼 得分:0
转字符串的话,为了区分,我加了*,到后面
我不知道

*242*125*242*125*
中怎么把  
242
125
242
125
拿出来
郁闷
发表于:2007-03-24 23:08:1022楼 得分:0
急糊涂了
把split忘了
发表于:2007-03-24 23:11:2023楼 得分:0
你你你   快玩笑所把split忘了
发表于:2007-03-24 23:23:4524楼 得分:0
byte[]   data   =   new   byte[]   {   0xf2,   0x7d,   0xf2,   0x7d,   1,   2,   3,   4,   5,   6,   7,   8,   9,   0,   0xeb,   0xeb,   0xb7,   0xeb,   0xeb,   0xb7,   0xeb,   0xb7,   0xf2,   0x7d,   0xf2,   0x7d,   32,   23,   43,   54,   0xeb,   0xb7,   0xeb,   0xb7,   0xf2,   0x7d,   0xf2,   0x7d,   12,   0xeb,   0xb7,   0xeb,   0xb7   };


            list <byte[]>   list   =   new   list <byte[]> ();

            int   flag   =   0;
            int   index   =   0;
            list <byte>   section   =   new   list <byte> ();

            foreach   (   byte   b   in   data   )
            {

            head:

                if   (   flag   ==   3   )
                {
                    if   (   b   ==   (byte)   0x7d   )
                        flag++;
                    else
                    {
                        flag   =   0;
                        goto   head;
                    }
                }

                if   (   flag   ==   2   )
                {
                    if   (   b   ==   (byte)   0xf2   )
                        flag++;
                    else
                    {
                        flag   =   0;
                        goto   head;
                    }
                }

                if   (   flag   ==   1   )
                {
                    if   (   b   ==   (byte)   0x7d   )
                        flag++;
                    else
                    {
                        flag   =   0;
                        goto   head;
                    }
                }

                if   (   b   ==   (byte)   0xf2   &&   flag   ==   0   )
                    flag++;

                if   (   flag   ==   4   )
                {
                    flag   =   5;
                    continue;
                }


                if   (   flag   >   4   )
                    section.add(   b   );


            end:

                if   (   flag   ==   8   )
                {

                    if   (   b   ==   (byte)   0xb7   )
                        flag++;
                    else
                    {
                        flag   =   5;
                        goto   end;
                    }
                }

                if   (   flag   ==   7   )
                {
                    if   (   b   ==   (byte)   0xeb   )
                        flag++;
                    else
                    {
                        flag   =   5;
                        goto   end;
                    }
                }

                if   (   flag   ==   6   )
                {
                    if   (   b   ==   (byte)   0xb7   )
                        flag++;
                    else
                    {
                        flag   =   5;
                        goto   end;
                    }
                }

                if   (   b   ==   (byte)   0xeb   &&   flag   ==   5   )
                    flag++;

                if   (   flag   ==   9   )
                {
                    section.removerange(   section.count   -   4,   4   );
                    list.add(   section.toarray()   );
                    flag   =   0;

                    section   =   new   list <byte> ();
                }
            }


            foreach   (   byte[]   arr   in   list   )
            {
                foreach   (   byte   b   in   arr   )
                {
                    console.write(   "{0},   ",   convert.tostring(   b,   16   )   );
                }

                console.writeline();
            }
发表于:2007-03-24 23:28:2925楼 得分:0
正则表达式:

@ "242!125!242!125(? <content> .+)xxx!yyy!xxx!yyy "
发表于:2007-03-24 23:32:2226楼 得分:0
如果帧头或帧尾的结构不是这种abab而是abac类型的结构的话,则上面的状态机也不能正常工作,不过像正则表达式这样的带回溯的状态机本来就是很麻烦的。
发表于:2007-03-24 23:40:3527楼 得分:0
太感谢了。
现在还不是太懂。测试完了好好学习学习。
谢谢。
字符串的也刚弄出来了,呵呵。

ivony(授人以鱼不如授人以渔,上海谋生)   (   两星(中级))  
谢谢。


快速检索

最新资讯
热门点击