山茶花关键时刻表Sigmas

时间:2016-07-26 08:45:54

标签: camellia

Camellia在其关键时间表中使用6个sigma,值为

 Sigma1 = 0xA09E667F3BCC908B;
 Sigma2 = 0xB67AE8584CAA73B2;
 Sigma3 = 0xC6EF372FE94F82BE;
 Sigma4 = 0x54FF53A5F1D36F1C;
 Sigma5 = 0x10E527FADE682D1D;
 Sigma6 = 0xB05688C2B3E6C1FD;

山茶花的规范文件说“Sigmas被定义为从第二个十六进制位置到第二个十六进制位置的连续值 第i个素数的平方根的十六进制表示的第十七个十六进制位置。“

在这种情况下,第i个素数是2,3,5,7,11,13

但是我找不到计算这些常数的方法。计算素数的平方根很简单,但这些小数平方根如何转换成十六进制表示法?如何在c#中实现?

1 个答案:

答案 0 :(得分:2)

你需要的是一些主要计算平方根的方法。

请参阅以下Java应用程序。

private static final BigDecimal SQRT_DIG = new BigDecimal(150);
private static final BigDecimal SQRT_PRE = new BigDecimal(10).pow(SQRT_DIG.intValue());
private static final int HEX_DIGITS = 16;
private static final int HEX_DIGITS_REQUIRED = 16;
private static final int HEX_DIGITS_SKIPPED = 2;
// constant that puts the required number at the left hand of the decimal point
private static final BigDecimal DIGIT_MULTIPLICATION =
        new BigDecimal(BigInteger.valueOf(HEX_DIGITS).pow(HEX_DIGITS_SKIPPED + HEX_DIGITS_REQUIRED));

public static void main(String[] args) {

    // - starting value (prime)
    BigInteger currentBI = BigInteger.valueOf(2);

    // - loop 6 times
    for (int i = 1; i <= 6; i++) {
        // - get i'th prime
        while (!currentBI.isProbablePrime(Integer.MAX_VALUE)) {
            currentBI = currentBI.add(BigInteger.ONE);
        }

        // - as BigDecimal
        BigDecimal currentBD = BigDecimal.valueOf(currentBI.longValue());

        // - square root
        BigDecimal sqrt = bigSqrt(currentBD);

        // - put the required hex digits at the left hand of the decimal dot
        BigInteger digitsAtLeft = sqrt.multiply(DIGIT_MULTIPLICATION).toBigInteger();

        // - convert to hexadecimals and skip the first two digits as required
        String digits = digitsAtLeft.toString(HEX_DIGITS).substring(HEX_DIGITS_SKIPPED);

        // - print out
        System.out.printf("%d %d %f... %s%n",
                i, currentBI, sqrt, digits);

        // - current++
        currentBI = currentBI.add(BigInteger.ONE);
    }
}

/**
 * Uses Newton Raphson to compute the square root of a BigDecimal.
 * 
 * @author Luciano Culacciatti 
 * @url http://www.codeproject.com/Tips/257031/Implementing-SqrtRoot-in-BigDecimal
 */
public static BigDecimal bigSqrt(BigDecimal c){
    return sqrtNewtonRaphson(c,new BigDecimal(1),new BigDecimal(1).divide(SQRT_PRE));
}

private static BigDecimal sqrtNewtonRaphson  (BigDecimal c, BigDecimal xn, BigDecimal precision){
    BigDecimal fx = xn.pow(2).add(c.negate());
    BigDecimal fpx = xn.multiply(new BigDecimal(2));
    BigDecimal xn1 = fx.divide(fpx,2*SQRT_DIG.intValue(), RoundingMode.HALF_DOWN);
    xn1 = xn.add(xn1.negate());
    BigDecimal currentSquare = xn1.pow(2);
    BigDecimal currentPrecision = currentSquare.subtract(c);
    currentPrecision = currentPrecision.abs();
    if (currentPrecision.compareTo(precision) <= -1){
        return xn1;
    }
    return sqrtNewtonRaphson(c, xn1, precision);
}

这将输出:

1 2 1.414214... a09e667f3bcc908b2
2 3 1.732051... b67ae8584caa73b25
3 5 2.236068... c6ef372fe94f82be7
4 7 2.645751... 54ff53a5f1d36f1ce
5 11 3.316625... 10e527fade682d1de
6 13 3.605551... b05688c2b3e6c1fdb

问题是C#不知道BigDecimal,但您可以获得良好的精确decimal值,请尝试以下平方根计算here