Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/300.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 斐波那契LFSRs计算优化_C#_Php_Perl_Cryptography_Mathematical Optimization - Fatal编程技术网

C# 斐波那契LFSRs计算优化

C# 斐波那契LFSRs计算优化,c#,php,perl,cryptography,mathematical-optimization,C#,Php,Perl,Cryptography,Mathematical Optimization,是在维基上描述的,非常简单。 我想计算一些斐波那契LFSR的周期,然后使用生成的序列进行加密。 让我们以wiki为例: x16+x14+x13+x11+1 //来自wiki的代码: 包括 uint16_t lfsr=0xACE1u; 无符号位; 无符号周期=0; 做{ /*抽头:161311;特征多项式:x^16+x^14+x^13+x^11+1*/ 位=((lfsr>>0)^(lfsr>>2)^(lfsr>>3)^(lfsr>>5))&1; lfsr=(lfsr>>1)|(位>0; 对于($i

是在维基上描述的,非常简单。
我想计算一些斐波那契LFSR的周期,然后使用生成的序列进行加密。
让我们以wiki为例:

x16+x14+x13+x11+1

//来自wiki的代码:
包括
uint16_t lfsr=0xACE1u;
无符号位;
无符号周期=0;
做{
/*抽头:161311;特征多项式:x^16+x^14+x^13+x^11+1*/
位=((lfsr>>0)^(lfsr>>2)^(lfsr>>3)^(lfsr>>5))&1;
lfsr=(lfsr>>1)|(位>0;
对于($i=1;$i<$n;$i++){
//位^=lfsr>>2^lfst>>3^lfst>>5;
$bit=gmp\u xor($bit,(gmp\u div\u q($lfsr,gmp\u pow(2,$polynoms[$i])));
}
//位&=1;
$bit=gmp_和($bit,1);

//lfsr=$lfsr>>1 |$lsfr对于像x^321+…;这样的多项式,你根本不能这样做

如果多项式选择得当,则周期长度为2^231-1, 这大约是4.27*10^96。如果我没弄错的话,这个数字是 被认为超过了宇宙中原子的数量。。。 (严格地说,我指的是发布的C代码,因为我不懂php,但这肯定没什么区别。)

然而,有一种数学方法可以计算周期长度,而不进行蛮力攻击。不幸的是,这不能用几行来解释。如果你有扎实的数学背景(特别是有限域中的计算),我很乐意为你寻找有用的参考资料

编辑: 计算通过使用多项式p(x)获得的LFSR周期的第一步是获得p(x)mod 2的因式分解,即在GF(2)中。为此,我建议使用Mathematica或Maple等软件(如果可用)。您也可以尝试免费提供的Sage,有关用法的详细信息,请参见例如

p(x)的周期由其顺序e给出,这意味着p(x)除以x^e+1的最小数。不幸的是,我目前无法提供更多信息,我需要几天的时间来查找几年前我上过的一门课程的课堂讲稿


一个小例子:p(x)=(x^5+x^4+1)=(x^3+x+1)*(x^2+x+1),单个周期为2^3-1=7和2^2-1=3,由于所有多项式因子都不同,因此p(x)的周期是3×7=21,我在C++中也被验证过。

为了优化这一点,我们需要记住PHP在解析代码时有很大的开销,因为它没有编译,所以我们需要尽可能多地为它做工作。你应该总是用XDebug + KCachegrind来配置你的CPU /内存敏感代码(例如)查看PHP在哪里浪费了大部分时间。对于您的代码,只有12%的时间用于gmp_*函数计算,大部分时间用于代码解析

在我的笔记本电脑上(速度相当慢),我的代码运行2.4秒而不是3.5秒,但是对于更大的程度来说,差异应该更明显(例如19次幂给19秒对28秒)。这并不多,但确实是一些

我在代码中留下了注释,但如果您有一些问题,请随意提问。我使用函数创建来替换主循环中的“for($I=1;$I<$n;$I++)”循环

另外,我认为您应该将$period变量的类型更改为GMP(将$period++更改为GMP_*函数),因为它可以大于系统上的最大整数

function getPeriod() {
    $polynoms = array(16, 14, 13, 11);


    $highest = $polynoms[0];
    $input = $highest - 1;

    //Delete first element of array - we don't need it anyway
    array_shift($polynoms);

    $polynoms_count = count($polynoms);

    //You always repeat gmp_pow(2, $input) and it's result is constant,
    //so better precalculate it once.
    $input_pow = gmp_pow(2, $input);

    //Start function creation.
    //If you don't use PHP accelerators, then shorter variable names
    //work slightly faster, so I replaced some of names
    //$perion->$r,$bit -> $b, $lfsr -> $l, $polynoms -> $p
    $function_str = '$r=0;';
    $function_str .= 'do{';

    //Now we need to get rid of your loop inside loop, we can generate
    //static functions chain to replace it.
    //Also, PHP parses all PHP tokens, even ';' and it takes some time,
    //So, we should write as much one-liners as we can.
    $function_str .= '$b=gmp_xor($b=$l';


    foreach ($polynoms AS $id => &$polynom) {
        //You always repeat gmp_pow(2, $polynoms[$i]) and it's result is constant,
        //so better precalculate it once.
        $polynom = gmp_pow(2, $highest - $polynom);

        //We create our functions chain here
        if ($id < $polynoms_count - 1) {
            $function_str.=',gmp_xor(gmp_div_q($l,  $p[' . $id . '])';
        } else {
            $function_str.=',gmp_div_q($l,  $p[' . $id . '])';
        }
    }

    //Close all brackets
    $function_str.=str_repeat(')', $polynoms_count);

    //I don't know how to optimize the following, so I left it without change
    $function_str.=';';
    $function_str.='$l = gmp_or((gmp_div_q($l, 2)), (gmp_mul(gmp_and($b, 1), $i_p)));';
    $function_str.='$r++;';
    $function_str.='} while (gmp_cmp($l, 0x1));';
    $function_str.='return $r;';

    //Now, create our funciton
    $function = create_function('$l,$p,$i_p', $function_str);


    //Set begining states
    $lfsr = 0x1;
    $lfsr = gmp_init($lfsr, 16);


    //Run function
    $period = $function($lfsr, $polynoms, $input_pow);

    //Use result
    echo '<br />period = ' . $period;
    return $period;
}
函数getPeriod(){
$polynoms=数组(16,14,13,11);
$highest=$polynoms[0];
$input=$highest-1;
//删除数组的第一个元素-我们无论如何都不需要它
数组移位($polynoms);
$polynoms\u count=计数($polynoms);
//你总是重复gmp_pow(2,$input),结果是常数,
//所以最好预先计算一下。
$input_pow=gmp_pow(2$input);
//开始函数创建。
//如果不使用PHP加速器,则使用更短的变量名
//工作稍微快一点,所以我换了一些名字
//$perion->$r、$bit->$b、$lfsr->$l、$polynoms->$p
$function_str='$r=0;';
$function_str.='do{';
//现在我们需要去掉循环中的循环,我们可以生成
//静态功能链来取代它。
//此外,PHP解析所有PHP标记,甚至“;”,这需要一些时间,
//所以,我们应该尽可能多地写一行。
$function_str.='$b=gmp_xor($b=$l';
foreach($polynoms作为$id=>&$polynoms){
//你总是重复gmp_pow(2,$polynoms[$i]),结果是常数,
//所以最好预先计算一下。
$polynom=gmp_pow(2,$highest-$polynom);
//我们在这里创建我们的功能链
如果($id<$polynoms\u计数-1){
$function_str.=',gmp_xor(gmp_div_q($l,$p['.$id.]]);
}否则{
$function_str.=',gmp_div_q($l,$p['.$id.]]);
}
}
//关闭所有括号
$function_str.=str_repeat('),$polynoms_count);
//我不知道如何优化以下内容,所以我没有做任何更改
$function_str.=';';
$function_str.='$l=gmp_或((gmp_div_q($l,2)),(gmp_mul(gmp_和($b,1),$i_p));
$function_str.='$r++;';
$function_str.='}while(gmp_cmp($l,0x1));
$function_str.='return$r;';
//现在,创建我们的函数
$function=create_函数('$l,$p,$i_p',$function_str);
//设定起始状态
$lfsr=0x1;
$lfsr=gmp_init($lfsr,16);
//运行函数
$period=$function($lfsr、$polynoms、$input\u pow);
//使用结果
回显“
期间=”.$period; 返回期间; }
看起来您读错了。应该没有乘法,没有幂运算。都是使用逐位运算符完成的。您不需要任何特殊的库。^在C中表示xor。在PHP中也是如此。如果使用位操作,速度会非常快。使用位操作有一个大问题:32位(x86)这意味着如果我试着做
1hmm是的,你做了吗
function getPeriod(){
    $polynoms = array(16, 14, 13, 11);
    $input = $polynoms[0] - 1;
    $n = sizeof($polynoms);
    for ($i = 1; $i < $n; $i++)
        $polynoms[$i] = $polynoms[0] - $polynoms[$i];
    $polynoms[0] = 0;
    //reversed polynoms == array(0, 2, 3, 5);
    $lfsr = 0x1; //begining state       
    $period = 0;
    //gmp -- php library for long numbers;
    $lfsr = gmp_init($lfsr, 16);
    do {            
        $bit = $lfsr; //bit = x^16 >> 0;

        for($i = 1; $i < $n; $i++) {
            //bit ^= lfsr >> 2 ^ lfst >> 3 ^ lfst >> 5;
            $bit = gmp_xor($bit, ( gmp_div_q($lfsr, gmp_pow(2, $polynoms[$i])) ));                  
        }
        //bit &= 1;
        $bit = gmp_and($bit, 1);            
        //lfsr = $lfsr >> 1 | $lsfr << (16 - 1);
        $lfsr = gmp_or( (gmp_div_q($lfsr, 2)), (gmp_mul($bit, gmp_pow(2, $input))) );

        $period++;
    } while (gmp_cmp($lfsr, 0x1) != 0);
    echo '<br />period = '.$period;
    //period == 65535 == 2^16 - 1; -- and that's correct;
            //                        I hope, at least;
    return $period;
}
function getPeriod() {
    $polynoms = array(16, 14, 13, 11);


    $highest = $polynoms[0];
    $input = $highest - 1;

    //Delete first element of array - we don't need it anyway
    array_shift($polynoms);

    $polynoms_count = count($polynoms);

    //You always repeat gmp_pow(2, $input) and it's result is constant,
    //so better precalculate it once.
    $input_pow = gmp_pow(2, $input);

    //Start function creation.
    //If you don't use PHP accelerators, then shorter variable names
    //work slightly faster, so I replaced some of names
    //$perion->$r,$bit -> $b, $lfsr -> $l, $polynoms -> $p
    $function_str = '$r=0;';
    $function_str .= 'do{';

    //Now we need to get rid of your loop inside loop, we can generate
    //static functions chain to replace it.
    //Also, PHP parses all PHP tokens, even ';' and it takes some time,
    //So, we should write as much one-liners as we can.
    $function_str .= '$b=gmp_xor($b=$l';


    foreach ($polynoms AS $id => &$polynom) {
        //You always repeat gmp_pow(2, $polynoms[$i]) and it's result is constant,
        //so better precalculate it once.
        $polynom = gmp_pow(2, $highest - $polynom);

        //We create our functions chain here
        if ($id < $polynoms_count - 1) {
            $function_str.=',gmp_xor(gmp_div_q($l,  $p[' . $id . '])';
        } else {
            $function_str.=',gmp_div_q($l,  $p[' . $id . '])';
        }
    }

    //Close all brackets
    $function_str.=str_repeat(')', $polynoms_count);

    //I don't know how to optimize the following, so I left it without change
    $function_str.=';';
    $function_str.='$l = gmp_or((gmp_div_q($l, 2)), (gmp_mul(gmp_and($b, 1), $i_p)));';
    $function_str.='$r++;';
    $function_str.='} while (gmp_cmp($l, 0x1));';
    $function_str.='return $r;';

    //Now, create our funciton
    $function = create_function('$l,$p,$i_p', $function_str);


    //Set begining states
    $lfsr = 0x1;
    $lfsr = gmp_init($lfsr, 16);


    //Run function
    $period = $function($lfsr, $polynoms, $input_pow);

    //Use result
    echo '<br />period = ' . $period;
    return $period;
}