美文网首页
0x7e相关转义

0x7e相关转义

作者: liurongming | 来源:发表于2017-09-05 08:41 被阅读0次

    PPP数据成帧转义,C语言实现

    #include <stdio.h>
    #include <string.h>
    
    // PPP数据帧每一帧都以标识字符0x7E开始和结束;
    // 由于标识字符的值是0x7E,因此当该字符出现在信息字段中时,PPP需要对它进行转义。
    // 当PPP使用异步传输时,它把转义字符定义为:0x7D,并使用字节填充RFC-1662标准。
    // 字节填充RFC-1662标准规定如下:
    // 1. 把信息字段中出现的每一个0x7E字符转变成字节序列(0x7D,0x5E)
    // 2. 若信息字段中出现一个0x7D的字节(即出现了与转义字符相同的比特组合),
    //    则把0x7D转义成两个字节序列(0x7D,0x5D)
    // 3. 若信息字段中出现ASCII码的控制字符(即数值小于0x20的字符),
    //    则在该字符前面加入一个0x7D字节,同时将该字符的编码加以改变
    
    #define PPP_FRAME_FLAG        ( 0x7E )    /* 标识字符 */
    #define PPP_FRAME_ESC        ( 0x7D )    /* 转义字符 */
    #define PPP_FRAME_ENC        ( 0x20 )    /* 编码字符 */
    
    int ppp_encode(unsigned char *in, int in_len, unsigned char *out, int *out_len)
    {
        unsigned char *pi, *po;
        int i, tmp_len;
    
        pi = in;
        po = out;
        tmp_len = in_len;
    
        for(i = 0; i < in_len; i++)
        {
            if( *pi == PPP_FRAME_FLAG || *pi == PPP_FRAME_ESC || *pi < 0x20 )
            {
                *po = PPP_FRAME_ESC;
                po++;
                tmp_len++;
                *po = *pi ^ PPP_FRAME_ENC;
            }
            else
            {
                *po = *pi;
            }
    
            pi++;
            po++;
        }
        *out_len = tmp_len;
    
        return 0;
    }
    
    int ppp_decode(unsigned char *in, int in_len, unsigned char *out, int *out_len)
    {
        unsigned char *pi, *po;
        int i, tmp_len;
    
        pi = in;
        po = out;
        tmp_len = in_len;
    
        for(i = 0; i < in_len; i++)
        {
            if(*pi == PPP_FRAME_ESC)
            {
                pi++;
                tmp_len--;
                *po = *pi ^ PPP_FRAME_ENC;
    
                i++;
            }
            else
            {
                *po = *pi;
            }
    
            pi++;
            po++;
        }
        *out_len = tmp_len;
    
        return 0;
    }
    
    
    void printf_hex(char *title, unsigned char *hex, int n)
    {
        int i;
    
        printf("%s", title);
        for(i = 0; i < n; i++)
        {
            if(i % 16 == 0 && i != 0)
                printf("\r\n");
            printf("%02x ", (unsigned char )hex[i]);
        }
        printf("\r\n");
    }
    
    int main(void)
    {
        unsigned char p1[256];
        unsigned char p2[512];
        unsigned char p3[512];
        int i, len1, len2, len3;
    
        len1 = sizeof(p1)/sizeof(p1[0]);
    
        for(i = 0; i < len1; i++)
        {
            p1[i] = i % 256;
        }
    
        printf_hex("Before Encode::\r\n", p1, len1);
        printf("Before Encode, len1: %d\r\n", len1);
    
        ppp_encode(p1, len1, p2, &len2);
    
        printf_hex("After Encode::\r\n", p2, len2);
        printf("After Encode, len2: %d\r\n", len2);
    
        ppp_decode(p2, len2, p3, &len3);
    
        printf_hex("After Decode::\r\n", p3, len3);
        printf("After Decode, len3: %d\r\n", len3);
    
        return 0;
    }
    

    PPP数据成帧转义,JAVA语言实现

    private static final char PPP_FRAME_FLAG = 0x7E;
        private static final char PPP_FRAME_ESC = 0x7D;
        private static final char PPP_FRAME_ENC = 0x20;
    
        // PPP数据帧每一帧都以标识字符0x7E开始和结束;
        // 由于标识字符的值是0x7E,因此当该字符出现在信息字段中时,PPP需要对它进行转义。
        // 当PPP使用异步传输时,它把转义字符定义为:0x7D,并使用字节填充RFC-1662标准。
        // 字节填充RFC-1662标准规定如下:
        // 1. 把信息字段中出现的每一个0x7E字符转变成字节序列(0x7D,0x5E)
        // 2. 若信息字段中出现一个0x7D的字节(即出现了与转义字符相同的比特组合),
        // 则把0x7D转义成两个字节序列(0x7D,0x5D)
        // 3. 若信息字段中出现ASCII码的控制字符(即数值小于0x20的字符),
        // 则在该字符前面加入一个0x7D字节,同时将该字符的编码加以改变
        public static char[] ppp_encode(char[] in) {
            StringBuffer sb = new StringBuffer();
            for (int i = 0; i < in.length; i++) {
                if (in[i] == PPP_FRAME_FLAG || in[i] == PPP_FRAME_ESC || in[i] < 0x20) {
                    sb.append((char) PPP_FRAME_ESC);
                    sb.append((char) (in[i] ^ PPP_FRAME_ENC));
                } else {
                    sb.append(in[i]);
                }
            }
            char[] out = sb.toString().toCharArray();
            return out;
        }
    
        // PPP数据帧每一帧都以标识字符0x7E开始和结束;
        // 由于标识字符的值是0x7E,因此当该字符出现在信息字段中时,PPP需要对它进行转义。
        // 当PPP使用异步传输时,它把转义字符定义为:0x7D,并使用字节填充RFC-1662标准。
        // 字节填充RFC-1662标准规定如下:
        // 1. 把信息字段中出现的每一个0x7E字符转变成字节序列(0x7D,0x5E)
        // 2. 若信息字段中出现一个0x7D的字节(即出现了与转义字符相同的比特组合),
        // 则把0x7D转义成两个字节序列(0x7D,0x5D)
        // 3. 若信息字段中出现ASCII码的控制字符(即数值小于0x20的字符),
        // 则在该字符前面加入一个0x7D字节,同时将该字符的编码加以改变
        public static char[] ppp_decode(char[] in) {
            printHex(in);
            StringBuffer sb = new StringBuffer();
            for (int i = 0; i < in.length; i++) {
                if (in[i] == PPP_FRAME_ESC) {
                    sb.append((char)(in[i+1] ^ PPP_FRAME_ENC));
                    i++;
                } else {
                    sb.append(in[i]);
                }
    
            }
            char[] out = sb.toString().toCharArray();
            printHex(out);
            return out;
        }
    

    串口数据成帧转义,C语言实现

    /*
     * 0x7e 转义
     *  0x7e = 0x7f 01
     *  0x7f = 0x7f 02
     */
    int mark_7e_encode(unsigned char *in, int in_len, unsigned char *out, int *out_len);
    
    /*
     * 0x7e 反转义
     *  0x7e = 0x7f 01
     *  0x7f = 0x7f 02
     */
    int mark_7e_decode(unsigned char *in, int in_len, unsigned char *out, int *out_len);
    
    #define MARK_7E        ( 0x7E )    /* 标识字符 */
    #define MARK_7F        ( 0x7F )    /* 转义字符 */
    #define MARK_01        ( 0x01 )    /* 转义字符 */
    #define MARK_02        ( 0x02 )    /* 转义字符 */
    
    int mark_7e_encode(unsigned char *in, int in_len, unsigned char *out, int *out_len)
    {
        unsigned char *pi, *po;
        int i, tmp_len;
    
        pi = in;
        po = out;
        tmp_len = in_len;
    
        for(i = 0; i < in_len; i++)
        {
            if( *pi == MARK_7E )
            {
                *po = MARK_7F;
                *(++po)  = MARK_01;
    
                tmp_len ++;
            }
            else if(*pi == MARK_7F){
                *po = MARK_7F;
                *(++po) = MARK_02;
                tmp_len ++;
            }
            else
            {
                *po = *pi;
            }
    
            pi++;
            po++;
        }
        *out_len = tmp_len;
    
        return 0;
    }
    
    int mark_7e_decode(unsigned char *in, int in_len, unsigned char *out, int *out_len)
    {
        unsigned char *pi, *po;
        int i, tmp_len;
    
        pi = in;
        po = out;
        tmp_len = in_len;
    
        for(i = 0; i < in_len; i++)
        {
            if((*pi == MARK_7F) &&  (*(pi + 1) == MARK_01))
            {
                *po = MARK_7E;
                po++;
                pi +=2;
                tmp_len--;
                i++;
            }else  if((*pi == MARK_7F) &&  (*(pi +1) == MARK_02)){
                *po = MARK_7F;
                po++;
                pi +=2;
                tmp_len--;
                i++;
            }
            else
            {
                *po = *pi;
                pi++;
                po++;
            }
        }
        *out_len = tmp_len;
    
        return 0;
    }
    
    void printf_hex(char *title, unsigned char *hex, int n)
    {
        int i;
    
        printf("%s", title);
        for(i = 0; i < n; i++)
        {
            if(i % 16 == 0 && i != 0)
                printf("\r\n");
            printf("%02x ", (unsigned char )hex[i]);
        }
        printf("\r\n");
    }
    
    int main(void)
    {
        unsigned char p1[256];
        unsigned char p2[512];
        unsigned char p3[512];
        int i, len1, len2, len3;
    
        len1 = sizeof(p1)/sizeof(p1[0]);
    
        for(i = 0; i < len1; i++)
        {
            p1[i] = i % 256;
        }
    
        printf_hex("Before Encode::\r\n", p1, len1);
        printf("Before Encode, len1: %d\r\n", len1);
    
        mark_7e_encode(p1, len1, p2, &len2);
    
        printf_hex("After Encode::\r\n", p2, len2);
        printf("After Encode, len2: %d\r\n", len2);
    
        mark_7e_decode(p2, len2, p3, &len3);
    
        printf_hex("After Decode::\r\n", p3, len3);
        printf("After Decode, len3: %d\r\n", len3);
    
        return 0;
    }
    

    串口数据成帧转义,JAVA语言实现

    private static final char MARK_7E = 0x7E;
        private static final char MARK_7F = 0x7F;
        private static final char MARK_01 = 0x01;
        private static final char MARK_02 = 0x02;
    
        public static char[] mark_7e_encode(char[] in) {
            StringBuffer sb = new StringBuffer();
            for (int i = 0; i < in.length; i++) {
                if (in[i] == MARK_7E) {
                    sb.append((char) MARK_7F);
                    sb.append((char) MARK_01);
    
                } else if (in[i] == MARK_7F) {
                    sb.append((char) MARK_7F);
                    sb.append((char) MARK_02);
    
                } else {
                    sb.append(in[i]);
                }
            }
            char[] out = sb.toString().toCharArray();
            return out;
        }
    
        public static char[] mark_7e_decode(char[] in) {
            StringBuffer sb = new StringBuffer();
            for (int i = 0; i < in.length; i++) {
                if ((in[i] == MARK_7F) && (in[i + 1] == MARK_01)) {
                    sb.append((char) MARK_7E);
                    i++;
                } else if ((in[i] == MARK_7F) && (in[i + 1] == MARK_02)) {
                    sb.append((char) MARK_7F);
                    i++;
                } else {
                    sb.append(in[i]);
                }
            }
            char[] out = sb.toString().toCharArray();
            return out;
        }
    

    相关文章

      网友评论

          本文标题:0x7e相关转义

          本文链接:https://www.haomeiwen.com/subject/dezyjxtx.html