为什么使用 Math.pow 的代码会打印出 "HELLO WORLD"?
Why does this code using Math.pow print "HELLO WORLD"?
我发现了以下代码。我知道,它看起来 weird/exciting 比 this one using seemingly random numbers, but it seems to be more complex than this one 对大数使用位移:
long[] c = {130636800L, -5080148640L, 13802573088L, -14974335980L, 8683908340L,
-3006955245L, 651448014L, -89047770L, 7457160L, -349165L, 6998L};
for (int x = 0; x < 11; x++) {
long s = 0;
for (int i = 0; i < 11; i++)
s += c[i] * Math.pow(x, i);
System.out.print((char)(s / 1814400));
}
输出:
HELLO WORLD
它是如何工作的?它是某种形式的加密还是有人疯狂地构建它?
让我们开始一些数学运算:
求解下面的方程式,你就会得到答案。这些方程只有一个解,因为方程的数量等于未知变量的数量。
设c[0] = 72
,即'H'的ASCII值。
为清楚起见:我使用 ^
表示符合惯例。现在解决:
1^0 * c[0] + 1^1 * c[1] + 1^2 * c[2] + 1^3 * c[3] + 1^4 * c[4] + 1^5 * c[5] + 1^6 * c[6] + 1^7 * c[7] + 1^8 * c[8] + 1^9 * c[9] + 1^10 * c[10] = 69
2^0 * c[0] + 2^1 * c[1] + 2^2 * c[2] + 2^3 * c[3] + 2^4 * c[4] + 2^5 * c[5] + 2^6 * c[6] + 2^7 * c[7] + 2^8 * c[8] + 2^9 * c[9] + 2^10 * c[10] = 76
3^0 * c[0] + 3^1 * c[1] + 3^2 * c[2] + 3^3 * c[3] + 3^4 * c[4] + 3^5 * c[5] + 3^6 * c[6] + 3^7 * c[7] + 3^8 * c[8] + 3^9 * c[9] + 3^10 * c[10] = 76
4^0 * c[0] + 4^1 * c[1] + 4^2 * c[2] + 4^3 * c[3] + 4^4 * c[4] + 4^5 * c[5] + 4^6 * c[6] + 4^7 * c[7] + 4^8 * c[8] + 4^9 * c[9] + 4^10 * c[10] = 79
5^0 * c[0] + 5^1 * c[1] + 5^2 * c[2] + 5^3 * c[3] + 5^4 * c[4] + 5^5 * c[5] + 5^6 * c[6] + 5^7 * c[7] + 5^8 * c[8] + 5^9 * c[9] + 5^10 * c[10] = 32
6^0 * c[0] + 6^1 * c[1] + 6^2 * c[2] + 6^3 * c[3] + 6^4 * c[4] + 6^5 * c[5] + 6^6 * c[6] + 6^7 * c[7] + 6^8 * c[8] + 6^9 * c[9] + 6^10 * c[10] = 87
7^0 * c[0] + 7^1 * c[1] + 7^2 * c[2] + 7^3 * c[3] + 7^4 * c[4] + 7^5 * c[5] + 7^6 * c[6] + 7^7 * c[7] + 7^8 * c[8] + 7^9 * c[9] + 7^10 * c[10] = 79
8^0 * c[0] + 8^1 * c[1] + 8^2 * c[2] + 8^3 * c[3] + 8^4 * c[4] + 8^5 * c[5] + 8^6 * c[6] + 8^7 * c[7] + 8^8 * c[8] + 8^9 * c[9] + 8^10 * c[10] = 82
9^0 * c[0] + 9^1 * c[1] + 9^2 * c[2] + 9^3 * c[3] + 9^4 * c[4] + 9^5 * c[5] + 9^6 * c[6] + 9^7 * c[7] + 9^8 * c[8] + 9^9 * c[9] + 9^10 * c[10] = 76
10^0 * c[0] + 10^1 * c[1] + 10^2 * c[2] + 10^3 * c[3] + 10^4 * c[4] + 10^5 * c[5] + 10^6 * c[6] + 10^7 * c[7] + 10^8 * c[8] + 10^9 * c[9] + 10^10 * c[10] = 68
注意未知数的个数是c[1]
到c[10]
,所以是10个。我们知道c[0] = 72
,所以不是未知数,方程的个数是10个。
现在我们只需将所有数字乘以 1814400,在答案中除以相同值,所以它不会改变任何东西,或者通过求解方程式找到的答案可能不是整数,所以乘以 1814400 得到整数。
您可以使用 this code for solving simultaneous equations of any order.
求解这些方程式
受到的启发,我找到了另一种逆向计算的方法。代码的内部循环(包括输出行的除法)基本上表示以下多项式:
此多项式是针对代码外循环中的值 0 到 10 计算的,并生成生成的 ASCII 字符。所以问题是:如何适应 polynomial through given consecutive data points?
这里是 xi = i 的 my search results points to the term Newton polynomial. This is a so-called interpolation polynomial for a given set of data points. As the polynomial is calculated for the values 0 to 10, we have the special case 之一。因此,为了构造上述多项式,我们必须计算一些二项式系数。
首先我们要计算数据点上的divided differences(即ASCII编码函数输出):
0: H = <b>72</b>
1: E = 69 <b>-3</b>
2: L = 76 7 <b>10</b>
3: L = 76 0 -7 <b>-17</b>
4: O = 79 3 3 10 <b>27</b>
5: = 32 -47 -50 -53 -63 <b>-90</b>
6: W = 87 55 102 152 205 268 <b>358</b>
7: O = 79 -8 -63 -165 -317 -522 -790 <b>-1148</b>
8: R = 82 3 11 74 239 556 1078 1868 <b>3016</b>
9: L = 76 -6 -9 -20 -94 -333 -889 -1967 -3835 <b>-6851</b>
10: D = 68 -8 -2 7 27 121 454 1343 3310 7145 <b>13996</b>
然后,每列最上面的条目是我们构建插值多项式所需的系数:
72
- 3 / 1 x
+ 10 / 2 x(x-1)
- 17 / 6 x(x-1)(x-2)
+ 27 / 24 x(x-1)(x-2)(x-3)
- 90 / 120 x(x-1)(x-2)(x-3)(x-4)
+ 358 / 720 x(x-1)(x-2)(x-3)(x-4)(x-5)
- 1148 / 5040 x(x-1)(x-2)(x-3)(x-4)(x-5)(x-6)
+ 3016 / 40320 x(x-1)(x-2)(x-3)(x-4)(x-5)(x-6)(x-7)
- 6851 / 362880 x(x-1)(x-2)(x-3)(x-4)(x-5)(x-6)(x-7)(x-8)
+ 13996 / 3628800 x(x-1)(x-2)(x-3)(x-4)(x-5)(x-6)(x-7)(x-8)(x-9)
这里,分母代表n! (see the special case)。
通过扩展此公式(例如通过使用 WolframAlpha),您将得到如上所示的多项式。如果有人想知道,多项式如下所示:
我发现了以下代码。我知道,它看起来 weird/exciting 比 this one using seemingly random numbers, but it seems to be more complex than this one 对大数使用位移:
long[] c = {130636800L, -5080148640L, 13802573088L, -14974335980L, 8683908340L,
-3006955245L, 651448014L, -89047770L, 7457160L, -349165L, 6998L};
for (int x = 0; x < 11; x++) {
long s = 0;
for (int i = 0; i < 11; i++)
s += c[i] * Math.pow(x, i);
System.out.print((char)(s / 1814400));
}
输出:
HELLO WORLD
它是如何工作的?它是某种形式的加密还是有人疯狂地构建它?
让我们开始一些数学运算:
求解下面的方程式,你就会得到答案。这些方程只有一个解,因为方程的数量等于未知变量的数量。
设c[0] = 72
,即'H'的ASCII值。
为清楚起见:我使用 ^
表示符合惯例。现在解决:
1^0 * c[0] + 1^1 * c[1] + 1^2 * c[2] + 1^3 * c[3] + 1^4 * c[4] + 1^5 * c[5] + 1^6 * c[6] + 1^7 * c[7] + 1^8 * c[8] + 1^9 * c[9] + 1^10 * c[10] = 69
2^0 * c[0] + 2^1 * c[1] + 2^2 * c[2] + 2^3 * c[3] + 2^4 * c[4] + 2^5 * c[5] + 2^6 * c[6] + 2^7 * c[7] + 2^8 * c[8] + 2^9 * c[9] + 2^10 * c[10] = 76
3^0 * c[0] + 3^1 * c[1] + 3^2 * c[2] + 3^3 * c[3] + 3^4 * c[4] + 3^5 * c[5] + 3^6 * c[6] + 3^7 * c[7] + 3^8 * c[8] + 3^9 * c[9] + 3^10 * c[10] = 76
4^0 * c[0] + 4^1 * c[1] + 4^2 * c[2] + 4^3 * c[3] + 4^4 * c[4] + 4^5 * c[5] + 4^6 * c[6] + 4^7 * c[7] + 4^8 * c[8] + 4^9 * c[9] + 4^10 * c[10] = 79
5^0 * c[0] + 5^1 * c[1] + 5^2 * c[2] + 5^3 * c[3] + 5^4 * c[4] + 5^5 * c[5] + 5^6 * c[6] + 5^7 * c[7] + 5^8 * c[8] + 5^9 * c[9] + 5^10 * c[10] = 32
6^0 * c[0] + 6^1 * c[1] + 6^2 * c[2] + 6^3 * c[3] + 6^4 * c[4] + 6^5 * c[5] + 6^6 * c[6] + 6^7 * c[7] + 6^8 * c[8] + 6^9 * c[9] + 6^10 * c[10] = 87
7^0 * c[0] + 7^1 * c[1] + 7^2 * c[2] + 7^3 * c[3] + 7^4 * c[4] + 7^5 * c[5] + 7^6 * c[6] + 7^7 * c[7] + 7^8 * c[8] + 7^9 * c[9] + 7^10 * c[10] = 79
8^0 * c[0] + 8^1 * c[1] + 8^2 * c[2] + 8^3 * c[3] + 8^4 * c[4] + 8^5 * c[5] + 8^6 * c[6] + 8^7 * c[7] + 8^8 * c[8] + 8^9 * c[9] + 8^10 * c[10] = 82
9^0 * c[0] + 9^1 * c[1] + 9^2 * c[2] + 9^3 * c[3] + 9^4 * c[4] + 9^5 * c[5] + 9^6 * c[6] + 9^7 * c[7] + 9^8 * c[8] + 9^9 * c[9] + 9^10 * c[10] = 76
10^0 * c[0] + 10^1 * c[1] + 10^2 * c[2] + 10^3 * c[3] + 10^4 * c[4] + 10^5 * c[5] + 10^6 * c[6] + 10^7 * c[7] + 10^8 * c[8] + 10^9 * c[9] + 10^10 * c[10] = 68
注意未知数的个数是c[1]
到c[10]
,所以是10个。我们知道c[0] = 72
,所以不是未知数,方程的个数是10个。
现在我们只需将所有数字乘以 1814400,在答案中除以相同值,所以它不会改变任何东西,或者通过求解方程式找到的答案可能不是整数,所以乘以 1814400 得到整数。
您可以使用 this code for solving simultaneous equations of any order.
求解这些方程式受到
此多项式是针对代码外循环中的值 0 到 10 计算的,并生成生成的 ASCII 字符。所以问题是:如何适应 polynomial through given consecutive data points?
这里是 xi = i 的 my search results points to the term Newton polynomial. This is a so-called interpolation polynomial for a given set of data points. As the polynomial is calculated for the values 0 to 10, we have the special case 之一。因此,为了构造上述多项式,我们必须计算一些二项式系数。
首先我们要计算数据点上的divided differences(即ASCII编码函数输出):
0: H = <b>72</b>
1: E = 69 <b>-3</b>
2: L = 76 7 <b>10</b>
3: L = 76 0 -7 <b>-17</b>
4: O = 79 3 3 10 <b>27</b>
5: = 32 -47 -50 -53 -63 <b>-90</b>
6: W = 87 55 102 152 205 268 <b>358</b>
7: O = 79 -8 -63 -165 -317 -522 -790 <b>-1148</b>
8: R = 82 3 11 74 239 556 1078 1868 <b>3016</b>
9: L = 76 -6 -9 -20 -94 -333 -889 -1967 -3835 <b>-6851</b>
10: D = 68 -8 -2 7 27 121 454 1343 3310 7145 <b>13996</b>
然后,每列最上面的条目是我们构建插值多项式所需的系数:
72
- 3 / 1 x
+ 10 / 2 x(x-1)
- 17 / 6 x(x-1)(x-2)
+ 27 / 24 x(x-1)(x-2)(x-3)
- 90 / 120 x(x-1)(x-2)(x-3)(x-4)
+ 358 / 720 x(x-1)(x-2)(x-3)(x-4)(x-5)
- 1148 / 5040 x(x-1)(x-2)(x-3)(x-4)(x-5)(x-6)
+ 3016 / 40320 x(x-1)(x-2)(x-3)(x-4)(x-5)(x-6)(x-7)
- 6851 / 362880 x(x-1)(x-2)(x-3)(x-4)(x-5)(x-6)(x-7)(x-8)
+ 13996 / 3628800 x(x-1)(x-2)(x-3)(x-4)(x-5)(x-6)(x-7)(x-8)(x-9)
这里,分母代表n! (see the special case)。 通过扩展此公式(例如通过使用 WolframAlpha),您将得到如上所示的多项式。如果有人想知道,多项式如下所示: