0x7e相关转义

2017-09-05  本文已影响0人  liurongming

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;
    }
上一篇下一篇

猜你喜欢

热点阅读