L先生的回信

原题:L先生的回信

原题大意

L先生打算回复来自朋友Z的上一封信,可是他担心信的内容在网络传送过程中出现错误,于是打算采用CRC校验方式保证信息完整性,可是他不知道应该怎么做,请你为他求出应该发送的比特序列。

循环冗余校验码(CRC)的基本原理是:在K位信息码后再拼接R位的校验码,整个编码长度为N位,因此,这种编码也叫(N,K)码。对于一个给定的(N,K)码,可以证明存在一个最高次幂为N-K=R的多项式G(x)。根据G(x)可以生成K位信息的校验码,而G(x)叫做这个CRC码的生成多项式。 校验码的具体生成过程为:假设要发送的信息用多项式C(X)表示,将C(x)左移R位(可表示成C(x)2^R),这样C(x)的右边就会空出R位,这就是校验码的位置。用 C(x)2^R 除以(模2除法)生成多项式G(x)得到的余数就是校验码。

Input

多组测试例,处理到文件结束。(测试例<5)

每行有两个字符串,用空格隔开,分别为信的内容和生成多项式(长度<=50)。
信的内容为二进制表示。
生成多项式可能用x的多项式,也可能用二进制表示(格式见样例)。

Output

每行输出一个加入CRC后发送的二进制序列,该序列不会长度超过32。

算法分析

模拟。

程序代码

#include <bits/stdc++.h>
#define mem(a,b) memset(a,b,sizeof(a))
using namespace std;
string s, t, ss;
int n, r, k;
int read(int i,string t){
    int rr = 0;
    while(isdigit(t[i])){
        rr = rr*10+(t[i] - '0');
        i++;
    }
    return rr;
}
int main(){
    while(cin >> s >> t){
        ss = s;
        int num[100];
        if(t[0] == '0' || t[0] == '1'){
            r = t.length()-1;
            for(int i = 0; i <= r; i++)
                num[i] = t[i] - '0';
        }
        else{            
            r = read(1,t);
            for(int i = 0; i <= r; i++)
                num[i] = 0;
            int size = t.length();
            if(t[size - 1] == '1') num[r] = 1,size-=2;
            if(size >0 && (t[size - 1] == 'x' || t[size - 1] =='X')) num[r-1] = 1,size-=2;
            for(int i = 0; i < size; i++){
                int tt;
                if(isdigit(t[i])) 
                    {
                        tt = read(i,t);
                        num[r-tt] = 1;
                        while(isdigit(t[i])) i++;
                    }
            }

        }
        k = s.length();
        n = k + r;
        for(int i = k; i < n; i++){
            s += '0';
        }
        for(int i = 0; i < n-r; i++){
            if(s[i] != '0'){
                int tmp;
                int cnt = i, cur = 0;
                while(cur <= r){
                    tmp = (s[cnt] - '0') ^ num[cur];
                    s[cnt] = tmp+'0';
                    cur++;
                    cnt++;
                }
//                if(cnt == n) break;
            }
        }
        cout << ss;
        for(int i  = k; i < n; i++){
            cout << s[i];
        }
        cout << endl;
    }
    return 0;
}