On Monday, 30 August 2021 at 14:14:45 UTC+2, Tenjin wrote:
function g(s, C, m) {
console.log(String.fromCharCode(96 + C));
return (
(!C && !s[m]) ||
(C &&
s[m] &&
s[m++] == String.fromCharCode(96 + C) &&
f(s, (++C * C++ + C++ * ++C) >> ++m, --m))
I take that should read 'g', not 'f'.
);
}
onsubmit="alert((g(pass.value,1,0) ? 'Correct! The password is ' : 'Wrong! not ')+pass.value); return false;"
I need some help in finding what the correct password is. So far I understand that te first character must contain an "a"
1) Firstly, few transformations [best viewed in monospace]:
1.1) Some clean-up and fixes:
(Fixed the exit conditions: note that 'false || undefined' is 'undefined', not 'false'.)
function g_1(s, c, m) {
var L = s.length;
return (
(!c && m === L)
|| (c && m < L
&& s[m++] === String.fromCharCode(96+c)
&& g_1(s, (++c*c++ + c++*++c) >> ++m, --m))
);
}
1.2) Resolve increments:
function g_2(s, c, m) {
var L = s.length;
return (
(!c && m === L)
|| (c && m < L
&& s[m] === String.fromCharCode(96+c)
&& g_2(s, ((c+1)*(c+1) + (c+2)*(c+4)) >> (m+2), (m+1)))
);
}
1.3) Unwind recursion and subsume 'm':
(We can subsume 'm' since it is the index into the string, bound to start from zero.)
function g(s, c) {
var L = s.length;
if (c === 0) { // short-cut
return L === 0;
}
for (var m = 0; m < L; ++m) {
if(!(s[m] === String.fromCharCode(96+c))) {
return false;
}
c = (c+1)*(c+1) + (c+2)*(c+4) >> m+2;
}
return c === 0;
}
2) Now from 1.3 we can extract the password generator:
(There is in 1.3 simply a comparison char by char with the expected password, so we can extrapolate the logic that just produces the password.)
function h(c) {
var s = "";
for (var m = 0; c !== 0; ++m) {
s += String.fromCharCode(96+c);
c = (c+1)*(c+1) + (c+2)*(c+4) >> m+2;
}
return s;
}
T) Some basic (and quick) testing in the console:
(Preliminarily, copy-paste the functions g_1, g, and h in the console.)
T.1) Check the code transformation:
h(1)
<- "adiorlc"
g_1("adiorlc", 1, 0)
<- true
g_1("adiorlC", 1, 0)
<- false
g_1("adiorl", 1, 0)
<- false
g("adiorlc", 1)
<- true
g("adiorlC", 1)
<- false
g("adiorl", 1)
<- false
T.2) Test the roundtrip:
g(h(100), 100)
<- true
g(h(100), 99)
<- false
var lo = -9, hi = 5; for (var c = lo; c <= hi; ++c) { var s = h(c), e_1 = g_1(s, c, 0), e = g(s, c); console.log(c, s, e_1, e); }
-9 "Wxĉວ셭ﵗ黡繗目护눕뙉ꯡ찁ᗋȫa" true true
-8 "XrÄմ鸾늲户抉韙哵많䮑䰶ⵐࡄ" true true
-7 "Ylƥ᩻侚碸酟풂툲㒂ጕ鮐벋ቘā" true true
-6 "Zhy»ɼᨲ皏徕騐鼧弫Ⱪ빗ᩓ́c" true true
-5 "[diorlc" true true
-4 "\\bddb" true true
-3 "]" true true
-2 "^" true true
-1 "_" true true
0 "" true true
1 "adiorlc" true true
2 "bhy»ɼᨲ皏徕騐鼧弫Ⱪ빗ᩓ́c" true true
3 "clƥ᩻侚碸酟풂툲㒂ጕ鮐벋ቘā" true true
4 "drÄմ鸾늲户抉韙哵많䮑䰶ⵐࡄ" true true
5 "exĉວ셭ﵗ黡繗目护눕뙉ꯡ찁ᗋȫa" true true
<- undefined
Seems to work fine for all 'c' integer, but I have neither *proved* that, nor I have proved that 'h' always terminates.
N.B. It is definitely NOT a secure scheme...
Have fun,
Julio
--- SoupGate-Win32 v1.05
* Origin: fsxNet Usenet Gateway (21:1/5)