您的位置:首页 > 其它

GF(2^8)运算一一(二)

2016-10-12 11:46 246 查看
具体的运算算法

加法:

//直接异或运算就ok了


乘法:

unsigned char GFmul(unsigned char a, unsigned char b){
unsigned char result = 0;
if ((b&1)==1) result = a;
b = b >> 1;
for (int i = 0; i < 8; i++){
if ((a>127))
a = (a << 1) ^ 0x1b;
else
a = a << 1;
if((b&1) == 1){
result ^= a;
}
b >>= 1;
}
return result;
}


分析一下乘法原理:

总共要循环8次,每一次循环都需要判断b的最低位是否为1,a的最高位是否为1。如果b的最低位为1,那么就结果result就要与a进行异或运算。再判断a最高位是否为1,如果是的话那么a在左移之后还要异或 1B。大概差不多了吧。

乘法逆元:

//生成逆元表函数
void set_Inverse(){
unsigned char gen = 3;
Inverse[0] = 0;
Inverse[1] = 3;
for (int i = 2; i < 256; i++){
Inverse[i] = GFmul(Inverse[i-1], gen);
}
}
//查表函数
unsigned char inverse(unsigned char b){
//初始化
unsigned char result;
if (b == 0){
cout << (int)b << "没有逆元" <<endl; //0没有逆元
}
else {
for (int i = 1; i < 256; i++){
if (Inverse[i] == b) {
result = Inverse[255-i];
return result;
}
}
}
}


乘法逆元原理:

在GF(2^8)这个群里如果有g^x * g^y == 1(g是其中一个生成元)那么就会有x+y == 255。回到函数里面,第一个我利用生成元:3做254次乘法(第一个元素是0第二个元素是3)得到了一个以3为生成元重新排列的群。第二个就是查表函数了。暴力搜索出b所在的位置,然后255-b所在的位置的元素就是b的逆元。

离散对数:

void set_genrator(){
memset(Genrator, 0, sizeof(Genrator));
string buf;
int a;
ifstream GEN("一个包含有所有生成元的文件,可以自己生成,也可以上网找");
while (!GEN.eof()){
GEN >> buf;
a = change_int(buf);
Genrator[a] = 1;
}
GEN.close();
}

int genrator(unsigned char a, unsigned char b){
if (b == 0){
cout << (int)b << "没有离散对数!" <<endl;
}
else{
//多次使用乘法直到找到为止;
unsigned char mi = 1;
int y = 0;
while(1){
mi = GFmul(mi, a);
y++;
if(mi == b) return y;
}
}
}


离散对数原理:

这里需要用户输入一个“生成元”和一个X,首先要保证用户输入的生成元是一个真实的生成元。所以需要加一个判断。之后就是利用生成元做多次乘法做到值为X为止,循环次数就是离散对数了。

最后:仅是学生党随意写的用于交流学习,不喜勿喷,谢谢驻足的各位
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  算法