Initial commit
This commit is contained in:
parent
a9e69994dc
commit
2b88cc30b0
|
@ -1,129 +1,129 @@
|
|||
# Byte-compiled / optimized / DLL files
|
||||
__pycache__/
|
||||
*.py[cod]
|
||||
*$py.class
|
||||
|
||||
# C extensions
|
||||
*.so
|
||||
|
||||
# Distribution / packaging
|
||||
.Python
|
||||
build/
|
||||
develop-eggs/
|
||||
dist/
|
||||
downloads/
|
||||
eggs/
|
||||
.eggs/
|
||||
lib/
|
||||
lib64/
|
||||
parts/
|
||||
sdist/
|
||||
var/
|
||||
wheels/
|
||||
pip-wheel-metadata/
|
||||
share/python-wheels/
|
||||
*.egg-info/
|
||||
.installed.cfg
|
||||
*.egg
|
||||
MANIFEST
|
||||
|
||||
# PyInstaller
|
||||
# Usually these files are written by a python script from a template
|
||||
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
||||
*.manifest
|
||||
*.spec
|
||||
|
||||
# Installer logs
|
||||
pip-log.txt
|
||||
pip-delete-this-directory.txt
|
||||
|
||||
# Unit test / coverage reports
|
||||
htmlcov/
|
||||
.tox/
|
||||
.nox/
|
||||
.coverage
|
||||
.coverage.*
|
||||
.cache
|
||||
nosetests.xml
|
||||
coverage.xml
|
||||
*.cover
|
||||
*.py,cover
|
||||
.hypothesis/
|
||||
.pytest_cache/
|
||||
|
||||
# Translations
|
||||
*.mo
|
||||
*.pot
|
||||
|
||||
# Django stuff:
|
||||
*.log
|
||||
local_settings.py
|
||||
db.sqlite3
|
||||
db.sqlite3-journal
|
||||
|
||||
# Flask stuff:
|
||||
instance/
|
||||
.webassets-cache
|
||||
|
||||
# Scrapy stuff:
|
||||
.scrapy
|
||||
|
||||
# Sphinx documentation
|
||||
docs/_build/
|
||||
|
||||
# PyBuilder
|
||||
target/
|
||||
|
||||
# Jupyter Notebook
|
||||
.ipynb_checkpoints
|
||||
|
||||
# IPython
|
||||
profile_default/
|
||||
ipython_config.py
|
||||
|
||||
# pyenv
|
||||
.python-version
|
||||
|
||||
# pipenv
|
||||
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
||||
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
||||
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
||||
# install all needed dependencies.
|
||||
#Pipfile.lock
|
||||
|
||||
# PEP 582; used by e.g. github.com/David-OConnor/pyflow
|
||||
__pypackages__/
|
||||
|
||||
# Celery stuff
|
||||
celerybeat-schedule
|
||||
celerybeat.pid
|
||||
|
||||
# SageMath parsed files
|
||||
*.sage.py
|
||||
|
||||
# Environments
|
||||
.env
|
||||
.venv
|
||||
env/
|
||||
venv/
|
||||
ENV/
|
||||
env.bak/
|
||||
venv.bak/
|
||||
|
||||
# Spyder project settings
|
||||
.spyderproject
|
||||
.spyproject
|
||||
|
||||
# Rope project settings
|
||||
.ropeproject
|
||||
|
||||
# mkdocs documentation
|
||||
/site
|
||||
|
||||
# mypy
|
||||
.mypy_cache/
|
||||
.dmypy.json
|
||||
dmypy.json
|
||||
|
||||
# Pyre type checker
|
||||
.pyre/
|
||||
# Byte-compiled / optimized / DLL files
|
||||
__pycache__/
|
||||
*.py[cod]
|
||||
*$py.class
|
||||
|
||||
# C extensions
|
||||
*.so
|
||||
|
||||
# Distribution / packaging
|
||||
.Python
|
||||
build/
|
||||
develop-eggs/
|
||||
dist/
|
||||
downloads/
|
||||
eggs/
|
||||
.eggs/
|
||||
lib/
|
||||
lib64/
|
||||
parts/
|
||||
sdist/
|
||||
var/
|
||||
wheels/
|
||||
pip-wheel-metadata/
|
||||
share/python-wheels/
|
||||
*.egg-info/
|
||||
.installed.cfg
|
||||
*.egg
|
||||
MANIFEST
|
||||
|
||||
# PyInstaller
|
||||
# Usually these files are written by a python script from a template
|
||||
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
||||
*.manifest
|
||||
*.spec
|
||||
|
||||
# Installer logs
|
||||
pip-log.txt
|
||||
pip-delete-this-directory.txt
|
||||
|
||||
# Unit test / coverage reports
|
||||
htmlcov/
|
||||
.tox/
|
||||
.nox/
|
||||
.coverage
|
||||
.coverage.*
|
||||
.cache
|
||||
nosetests.xml
|
||||
coverage.xml
|
||||
*.cover
|
||||
*.py,cover
|
||||
.hypothesis/
|
||||
.pytest_cache/
|
||||
|
||||
# Translations
|
||||
*.mo
|
||||
*.pot
|
||||
|
||||
# Django stuff:
|
||||
*.log
|
||||
local_settings.py
|
||||
db.sqlite3
|
||||
db.sqlite3-journal
|
||||
|
||||
# Flask stuff:
|
||||
instance/
|
||||
.webassets-cache
|
||||
|
||||
# Scrapy stuff:
|
||||
.scrapy
|
||||
|
||||
# Sphinx documentation
|
||||
docs/_build/
|
||||
|
||||
# PyBuilder
|
||||
target/
|
||||
|
||||
# Jupyter Notebook
|
||||
.ipynb_checkpoints
|
||||
|
||||
# IPython
|
||||
profile_default/
|
||||
ipython_config.py
|
||||
|
||||
# pyenv
|
||||
.python-version
|
||||
|
||||
# pipenv
|
||||
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
||||
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
||||
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
||||
# install all needed dependencies.
|
||||
#Pipfile.lock
|
||||
|
||||
# PEP 582; used by e.g. github.com/David-OConnor/pyflow
|
||||
__pypackages__/
|
||||
|
||||
# Celery stuff
|
||||
celerybeat-schedule
|
||||
celerybeat.pid
|
||||
|
||||
# SageMath parsed files
|
||||
*.sage.py
|
||||
|
||||
# Environments
|
||||
.env
|
||||
.venv
|
||||
env/
|
||||
venv/
|
||||
ENV/
|
||||
env.bak/
|
||||
venv.bak/
|
||||
|
||||
# Spyder project settings
|
||||
.spyderproject
|
||||
.spyproject
|
||||
|
||||
# Rope project settings
|
||||
.ropeproject
|
||||
|
||||
# mkdocs documentation
|
||||
/site
|
||||
|
||||
# mypy
|
||||
.mypy_cache/
|
||||
.dmypy.json
|
||||
dmypy.json
|
||||
|
||||
# Pyre type checker
|
||||
.pyre/
|
||||
|
|
42
LICENSE
42
LICENSE
|
@ -1,21 +1,21 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2021 987123879113
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2021 987123879113
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
|
21
README.md
21
README.md
|
@ -1,2 +1,19 @@
|
|||
# euromix_irpass
|
||||
Dancing Stage Euromix - Internet Challenge password generator
|
||||
# euromix_irpass
|
||||
Dancing Stage Euromix - Internet Challenge password generator
|
||||
|
||||
## Usage
|
||||
```
|
||||
usage: keygen.py [-h] [--license LICENSE]
|
||||
|
||||
optional arguments:
|
||||
-h, --help show this help message and exit
|
||||
--license LICENSE, -k LICENSE
|
||||
Machine license key
|
||||
```
|
||||
|
||||
## Building Javascript
|
||||
Note: pscript is required to build the kicpass.js file required for the webpage.
|
||||
|
||||
```
|
||||
python3 -c "import pscript; pscript.script2js('kicpass.py')"
|
||||
```
|
||||
|
|
|
@ -0,0 +1,105 @@
|
|||
<!doctype html>
|
||||
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<style>
|
||||
body {
|
||||
font-family:Arial, Helvetica, sans-serif;
|
||||
background:#12232E;
|
||||
max-width: 1000px;
|
||||
padding:4% 4%;
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size:48px;
|
||||
color:#EEFBFB;
|
||||
text-align:center;
|
||||
}
|
||||
|
||||
#footer {
|
||||
color:white;
|
||||
width:100%;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#footer a {
|
||||
color: #4DA8DA;
|
||||
}
|
||||
|
||||
input {
|
||||
color:white;
|
||||
width:100%;
|
||||
border-radius:5px;
|
||||
transition:all 0.3s;
|
||||
box-sizing:border-box;
|
||||
}
|
||||
|
||||
::placeholder {
|
||||
font-family:Arial, Helvetica, sans-serif;
|
||||
color:#DBDBDB;
|
||||
font-weight:500;
|
||||
}
|
||||
|
||||
[type="text"] {
|
||||
font-family:Consolas, monaco, monospace;
|
||||
font-weight:500;
|
||||
font-size:48px;
|
||||
line-height:120px;
|
||||
|
||||
margin-bottom:15px;
|
||||
outline:0;
|
||||
background-color:#203647;
|
||||
border:2px solid #4DA8DA;
|
||||
padding:13px;
|
||||
}
|
||||
|
||||
[type="submit"] {
|
||||
font-weight:700;
|
||||
font-size:36px;
|
||||
line-height:120px;
|
||||
|
||||
margin-top:-4px;
|
||||
background:#007CC7;
|
||||
border:0;
|
||||
cursor:pointer;
|
||||
}
|
||||
|
||||
#password {
|
||||
font-weight:bold;
|
||||
font-size:56px;
|
||||
text-align:center;
|
||||
border:2px solid #203647;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<script src="kicpass.js"></script>
|
||||
<script>
|
||||
function generatePassword() {
|
||||
var serial = document.getElementById('serial').value;
|
||||
var password = generate_password(serial);
|
||||
document.getElementById('password').value = password;
|
||||
}
|
||||
</script>
|
||||
|
||||
<h1>Dancing Stage Euromix Internet Challenge Password Generator</h1>
|
||||
<br>
|
||||
|
||||
<form id="passform" action="javascript:generatePassword();">
|
||||
<input id="serial" type="text" placeholder="Machine License Key" minlength="21" maxlength="24" required />
|
||||
<input type="submit" value="GENERATE" />
|
||||
</form>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<input id="password" type="text" placeholder="Password" onfocus="this.select();" readonly />
|
||||
<br>
|
||||
<br>
|
||||
<div id="footer">
|
||||
Source code: <a href="https://github.com/987123879113/euromix_irpass">https://github.com/987123879113/euromix_irpass</a>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,50 @@
|
|||
import argparse
|
||||
import datetime
|
||||
import random
|
||||
import sys
|
||||
|
||||
import kicpass
|
||||
|
||||
|
||||
def seed_checker(minval, maxval):
|
||||
def seed_range_checker(arg):
|
||||
try:
|
||||
f = int(arg)
|
||||
|
||||
except ValueError:
|
||||
raise argparse.ArgumentTypeError("must be an integer")
|
||||
|
||||
if f < minval or f > maxval:
|
||||
raise argparse.ArgumentTypeError("must be in range [" + str(minval) + " .. " + str(maxval)+"]")
|
||||
|
||||
return f
|
||||
|
||||
return seed_range_checker
|
||||
|
||||
|
||||
def date_checker(val):
|
||||
try:
|
||||
f = int(val)
|
||||
|
||||
except ValueError:
|
||||
raise argparse.ArgumentTypeError("must be an integer")
|
||||
|
||||
if not rtcpass.verify_date(f):
|
||||
raise argparse.ArgumentTypeError("not a valid date")
|
||||
|
||||
return f
|
||||
|
||||
def get_current_date():
|
||||
now = datetime.datetime.now()
|
||||
date = "%02d%02d%02d" % ((now.year % 100), now.month, now.day)
|
||||
return int(date)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('--license', '-k', help='Machine license key', default="BWRBQE9132DXTKCRPRN64")
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
password = kicpass.generate_password(args.license)
|
||||
print(password)
|
|
@ -0,0 +1,813 @@
|
|||
/* Do not edit, autogenerated by pscript */
|
||||
|
||||
var _pyfunc_enumerate = function (iter) { // nargs: 1
|
||||
var i, res=[];
|
||||
if ((typeof iter==="object") && (!Array.isArray(iter))) {iter = Object.keys(iter);}
|
||||
for (i=0; i<iter.length; i++) {res.push([i, iter[i]]);}
|
||||
return res;
|
||||
};
|
||||
var _pyfunc_format = function (v, fmt) { // nargs: 2
|
||||
fmt = fmt.toLowerCase();
|
||||
var s = String(v);
|
||||
if (fmt.indexOf('!r') >= 0) {
|
||||
try { s = JSON.stringify(v); } catch (e) { s = undefined; }
|
||||
if (typeof s === 'undefined') { s = v._IS_COMPONENT ? v.id : String(v); }
|
||||
}
|
||||
var fmt_type = '';
|
||||
if (fmt.slice(-1) == 'i' || fmt.slice(-1) == 'f' ||
|
||||
fmt.slice(-1) == 'e' || fmt.slice(-1) == 'g') {
|
||||
fmt_type = fmt[fmt.length-1]; fmt = fmt.slice(0, fmt.length-1);
|
||||
}
|
||||
var i0 = fmt.indexOf(':');
|
||||
var i1 = fmt.indexOf('.');
|
||||
var spec1 = '', spec2 = ''; // before and after dot
|
||||
if (i0 >= 0) {
|
||||
if (i1 > i0) { spec1 = fmt.slice(i0+1, i1); spec2 = fmt.slice(i1+1); }
|
||||
else { spec1 = fmt.slice(i0+1); }
|
||||
}
|
||||
// Format numbers
|
||||
if (fmt_type == '') {
|
||||
} else if (fmt_type == 'i') { // integer formatting, for %i
|
||||
s = parseInt(v).toFixed(0);
|
||||
} else if (fmt_type == 'f') { // float formatting
|
||||
v = parseFloat(v);
|
||||
var decimals = spec2 ? Number(spec2) : 6;
|
||||
s = v.toFixed(decimals);
|
||||
} else if (fmt_type == 'e') { // exp formatting
|
||||
v = parseFloat(v);
|
||||
var precision = (spec2 ? Number(spec2) : 6) || 1;
|
||||
s = v.toExponential(precision);
|
||||
} else if (fmt_type == 'g') { // "general" formatting
|
||||
v = parseFloat(v);
|
||||
var precision = (spec2 ? Number(spec2) : 6) || 1;
|
||||
// Exp or decimal?
|
||||
s = v.toExponential(precision-1);
|
||||
var s1 = s.slice(0, s.indexOf('e')), s2 = s.slice(s.indexOf('e'));
|
||||
if (s2.length == 3) { s2 = 'e' + s2[1] + '0' + s2[2]; }
|
||||
var exp = Number(s2.slice(1));
|
||||
if (exp >= -4 && exp < precision) { s1=v.toPrecision(precision); s2=''; }
|
||||
// Skip trailing zeros and dot
|
||||
var j = s1.length-1;
|
||||
while (j>0 && s1[j] == '0') { j-=1; }
|
||||
s1 = s1.slice(0, j+1);
|
||||
if (s1.slice(-1) == '.') { s1 = s1.slice(0, s1.length-1); }
|
||||
s = s1 + s2;
|
||||
}
|
||||
// prefix/padding
|
||||
var prefix = '';
|
||||
if (spec1) {
|
||||
if (spec1[0] == '+' && v > 0) { prefix = '+'; spec1 = spec1.slice(1); }
|
||||
else if (spec1[0] == ' ' && v > 0) { prefix = ' '; spec1 = spec1.slice(1); }
|
||||
}
|
||||
if (spec1 && spec1[0] == '0') {
|
||||
var padding = Number(spec1.slice(1)) - (s.length + prefix.length);
|
||||
s = '0'.repeat(Math.max(0, padding)) + s;
|
||||
}
|
||||
return prefix + s;
|
||||
};
|
||||
var _pyfunc_int = function (x, base) { // nargs: 1 2
|
||||
if(base !== undefined) return parseInt(x, base);
|
||||
return x<0 ? Math.ceil(x): Math.floor(x);
|
||||
};
|
||||
var _pyfunc_list = function (x) {
|
||||
var r=[];
|
||||
if (typeof x==="object" && !Array.isArray(x)) {x = Object.keys(x)}
|
||||
for (var i=0; i<x.length; i++) {
|
||||
r.push(x[i]);
|
||||
}
|
||||
return r;
|
||||
};
|
||||
var _pyfunc_op_add = function (a, b) { // nargs: 2
|
||||
if (Array.isArray(a) && Array.isArray(b)) {
|
||||
return a.concat(b);
|
||||
} return a + b;
|
||||
};
|
||||
var _pyfunc_op_equals = function op_equals (a, b) { // nargs: 2
|
||||
var a_type = typeof a;
|
||||
// If a (or b actually) is of type string, number or boolean, we don't need
|
||||
// to do all the other type checking below.
|
||||
if (a_type === "string" || a_type === "boolean" || a_type === "number") {
|
||||
return a == b;
|
||||
}
|
||||
|
||||
if (a == null || b == null) {
|
||||
} else if (Array.isArray(a) && Array.isArray(b)) {
|
||||
var i = 0, iseq = a.length == b.length;
|
||||
while (iseq && i < a.length) {iseq = op_equals(a[i], b[i]); i+=1;}
|
||||
return iseq;
|
||||
} else if (a.constructor === Object && b.constructor === Object) {
|
||||
var akeys = Object.keys(a), bkeys = Object.keys(b);
|
||||
akeys.sort(); bkeys.sort();
|
||||
var i=0, k, iseq = op_equals(akeys, bkeys);
|
||||
while (iseq && i < akeys.length)
|
||||
{k=akeys[i]; iseq = op_equals(a[k], b[k]); i+=1;}
|
||||
return iseq;
|
||||
} return a == b;
|
||||
};
|
||||
var _pyfunc_op_error = function (etype, msg) { // nargs: 2
|
||||
var e = new Error(etype + ': ' + msg);
|
||||
e.name = etype
|
||||
return e;
|
||||
};
|
||||
var _pyfunc_op_instantiate = function (ob, args) { // nargs: 2
|
||||
if ((typeof ob === "undefined") ||
|
||||
(typeof window !== "undefined" && window === ob) ||
|
||||
(typeof global !== "undefined" && global === ob))
|
||||
{throw "Class constructor is called as a function.";}
|
||||
for (var name in ob) {
|
||||
if (Object[name] === undefined &&
|
||||
typeof ob[name] === 'function' && !ob[name].nobind) {
|
||||
ob[name] = ob[name].bind(ob);
|
||||
ob[name].__name__ = name;
|
||||
}
|
||||
}
|
||||
if (ob.__init__) {
|
||||
ob.__init__.apply(ob, args);
|
||||
}
|
||||
};
|
||||
var _pyfunc_op_mult = function (a, b) { // nargs: 2
|
||||
if ((typeof a === 'number') + (typeof b === 'number') === 1) {
|
||||
if (a.constructor === String) return _pymeth_repeat.call(a, b);
|
||||
if (b.constructor === String) return _pymeth_repeat.call(b, a);
|
||||
if (Array.isArray(b)) {var t=a; a=b; b=t;}
|
||||
if (Array.isArray(a)) {
|
||||
var res = []; for (var i=0; i<b; i++) res = res.concat(a);
|
||||
return res;
|
||||
}
|
||||
} return a * b;
|
||||
};
|
||||
var _pyfunc_range = function (start, end, step) {
|
||||
var i, res = [];
|
||||
var val = start;
|
||||
var n = (end - start) / step;
|
||||
for (i=0; i<n; i++) {
|
||||
res.push(val);
|
||||
val += step;
|
||||
}
|
||||
return res;
|
||||
};
|
||||
var _pymeth_append = function (x) { // nargs: 1
|
||||
if (!Array.isArray(this)) return this.append.apply(this, arguments);
|
||||
this.push(x);
|
||||
};
|
||||
var _pymeth_format = function () {
|
||||
if (this.constructor !== String) return this.format.apply(this, arguments);
|
||||
var parts = [], i = 0, i1, i2;
|
||||
var itemnr = -1;
|
||||
while (i < this.length) {
|
||||
// find opening
|
||||
i1 = this.indexOf('{', i);
|
||||
if (i1 < 0 || i1 == this.length-1) { break; }
|
||||
if (this[i1+1] == '{') {parts.push(this.slice(i, i1+1)); i = i1 + 2; continue;}
|
||||
// find closing
|
||||
i2 = this.indexOf('}', i1);
|
||||
if (i2 < 0) { break; }
|
||||
// parse
|
||||
itemnr += 1;
|
||||
var fmt = this.slice(i1+1, i2);
|
||||
var index = fmt.split(':')[0].split('!')[0];
|
||||
index = index? Number(index) : itemnr
|
||||
var s = _pyfunc_format(arguments[index], fmt);
|
||||
parts.push(this.slice(i, i1), s);
|
||||
i = i2 + 1;
|
||||
}
|
||||
parts.push(this.slice(i));
|
||||
return parts.join('');
|
||||
};
|
||||
var _pymeth_index = function (x, start, stop) { // nargs: 1 2 3
|
||||
start = (start === undefined) ? 0 : start;
|
||||
stop = (stop === undefined) ? this.length : stop;
|
||||
start = Math.max(0, ((start < 0) ? this.length + start : start));
|
||||
stop = Math.min(this.length, ((stop < 0) ? this.length + stop : stop));
|
||||
if (Array.isArray(this)) {
|
||||
for (var i=start; i<stop; i++) {
|
||||
if (_pyfunc_op_equals(this[i], x)) {return i;} // indexOf cant
|
||||
}
|
||||
} else if (this.constructor === String) {
|
||||
var i = this.slice(start, stop).indexOf(x);
|
||||
if (i >= 0) return i + start;
|
||||
} else return this.index.apply(this, arguments);
|
||||
var e = Error(x); e.name='ValueError'; throw e;
|
||||
};
|
||||
var _pymeth_join = function (x) { // nargs: 1
|
||||
if (this.constructor !== String) return this.join.apply(this, arguments);
|
||||
return x.join(this); // call join on the list instead of the string.
|
||||
};
|
||||
var _pymeth_repeat = function(count) { // nargs: 0
|
||||
if (this.repeat) return this.repeat(count);
|
||||
if (count < 1) return '';
|
||||
var result = '', pattern = this.valueOf();
|
||||
while (count > 1) {
|
||||
if (count & 1) result += pattern;
|
||||
count >>= 1, pattern += pattern;
|
||||
}
|
||||
return result + pattern;
|
||||
};
|
||||
var _pymeth_replace = function (s1, s2, count) { // nargs: 2 3
|
||||
if (this.constructor !== String) return this.replace.apply(this, arguments);
|
||||
var i = 0, i2, parts = [];
|
||||
count = (count === undefined) ? 1e20 : count;
|
||||
while (count > 0) {
|
||||
i2 = this.indexOf(s1, i);
|
||||
if (i2 >= 0) {
|
||||
parts.push(this.slice(i, i2));
|
||||
parts.push(s2);
|
||||
i = i2 + s1.length;
|
||||
count -= 1;
|
||||
} else break;
|
||||
}
|
||||
parts.push(this.slice(i));
|
||||
return parts.join('');
|
||||
};
|
||||
var EuromixIRPassword, KonamiMRand, generate_password, int_js_from_bytes, int_js_to_bytes, mul64, n2h, n2h_long, safe_div, safe_modulo, shl, shr, this_is_js;
|
||||
this_is_js = function flx_this_is_js () {
|
||||
return false;
|
||||
};
|
||||
|
||||
safe_modulo = function flx_safe_modulo (n, m) {
|
||||
if (("this_is_js()" && (n < 0))) {
|
||||
return (_pyfunc_op_add((n % m), m)) % m;
|
||||
}
|
||||
return n % m;
|
||||
};
|
||||
|
||||
n2h = function flx_n2h (a) {
|
||||
var a1, a2, h;
|
||||
if (true) { /* if this_is_js() */
|
||||
h = "0123456789abcdef";
|
||||
a1 = a % 16;
|
||||
a2 = Math.floor(a/16);
|
||||
return _pyfunc_op_add(h[a2], h[a1]);
|
||||
}
|
||||
return _pymeth_format.call("{:02x}", a);
|
||||
};
|
||||
|
||||
n2h_long = function flx_n2h_long (a) {
|
||||
var a1, h, ret;
|
||||
if (true) { /* if this_is_js() */
|
||||
h = "0123456789abcdef";
|
||||
ret = [];
|
||||
while (a > 0) {
|
||||
a1 = a % 16;
|
||||
a = safe_div(a, 16);
|
||||
ret = _pyfunc_op_add(([h[a1]]), ret);
|
||||
}
|
||||
return _pymeth_join.call("", ret);
|
||||
}
|
||||
return _pymeth_format.call("{:x}", a);
|
||||
};
|
||||
|
||||
shr = function flx_shr (a, n) {
|
||||
var bits, i, output;
|
||||
if (true) { /* if this_is_js() */
|
||||
a &= 4294967295;
|
||||
bits = (function list_comprehension (iter0) {var res = [];var i, i0;if ((typeof iter0 === "object") && (!Array.isArray(iter0))) {iter0 = Object.keys(iter0);}for (i0=0; i0<iter0.length; i0++) {i = iter0[i0];{res.push(((!_pyfunc_op_equals((a & (1 << i)), 0)))? (1) : (0));}}return res;}).call(this, _pyfunc_range(0, 32, 1)).slice(n);
|
||||
output = 0;
|
||||
for (i = 0; i < Math.min(bits.length, 32); i += 1) {
|
||||
output |= bits[i] << i;
|
||||
}
|
||||
return output;
|
||||
}
|
||||
return (a >> n) & 4294967295;
|
||||
};
|
||||
|
||||
shl = function flx_shl (a, n) {
|
||||
var bits, i, output, stub1_, stub1_i, stub1_i0, stub1_iter0;
|
||||
if (true) { /* if this_is_js() */
|
||||
a &= 4294967295;
|
||||
stub1_ = [];stub1_iter0 = _pyfunc_range(0, 32, 1);if ((typeof stub1_iter0 === "object") && (!Array.isArray(stub1_iter0))) {stub1_iter0 = Object.keys(stub1_iter0);}for (stub1_i0=0; stub1_i0<stub1_iter0.length; stub1_i0++) {stub1_i = stub1_iter0[stub1_i0];{stub1_.push(((!_pyfunc_op_equals((a & (1 << stub1_i)), 0)))? (1) : (0));}}
|
||||
bits = stub1_;
|
||||
output = 0;
|
||||
for (i = Math.min(n, 32); i < 32; i += 1) {
|
||||
output |= bits[i - n] << i;
|
||||
}
|
||||
return output;
|
||||
}
|
||||
return (a << n) & 4294967295;
|
||||
};
|
||||
|
||||
mul64 = function flx_mul64 (a, b) {
|
||||
var ah, al, bh, bl, rl, rm1, rm1l, rm2, rm2l, rml;
|
||||
if (true) { /* if this_is_js() */
|
||||
al = a & 65535;
|
||||
ah = shr(a, 16);
|
||||
bl = b & 65535;
|
||||
bh = shr(b, 16);
|
||||
rl = _pyfunc_op_mult(al, bl);
|
||||
rm1 = _pyfunc_op_mult(ah, bl);
|
||||
rm2 = _pyfunc_op_mult(al, bh);
|
||||
rm1l = rm1 & 65535;
|
||||
rm2l = rm2 & 65535;
|
||||
rml = _pyfunc_op_add(rm1l, rm2l) & 65535;
|
||||
rl = _pyfunc_op_add(rl, shl(rml, 16));
|
||||
return rl;
|
||||
}
|
||||
return _pyfunc_op_mult(a, b) & 4294967295;
|
||||
};
|
||||
|
||||
safe_div = function flx_safe_div (n, m) {
|
||||
var i;
|
||||
if (true) { /* if this_is_js() */
|
||||
if ((((_pyfunc_op_equals((m & (m - 1)), 0))) && ((!_pyfunc_op_equals(m, 0))))) {
|
||||
for (i = 0; i < 32; i += 1) {
|
||||
if ((_pyfunc_op_equals(Math.pow(2, i), m))) {
|
||||
return shr(n, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
return Math.floor(n/m);
|
||||
}
|
||||
return Math.floor(n/m);
|
||||
};
|
||||
|
||||
int_js_to_bytes = function flx_int_js_to_bytes (data, length, endianness) {
|
||||
endianness = (endianness === undefined) ? "big": endianness;
|
||||
if (true) { /* if this_is_js() */
|
||||
if (!(_pyfunc_op_equals(endianness, "big"))) { throw _pyfunc_op_error('AssertionError', "_pyfunc_op_equals(endianness, \"big\")");}
|
||||
if (_pyfunc_op_equals(length, 1)) {
|
||||
return data[0];
|
||||
} else if (_pyfunc_op_equals(length, 2)) {
|
||||
return [shr(data, 8) & 255, data & 255];
|
||||
} else if (_pyfunc_op_equals(length, 4)) {
|
||||
return [shr(data, 24) & 255, shr(data, 16) & 255, shr(data, 8) & 255, data & 255];
|
||||
}
|
||||
if (!(_pyfunc_op_equals(length, 1) || _pyfunc_op_equals(length, 2) || _pyfunc_op_equals(length, 4))) { throw _pyfunc_op_error('AssertionError', "_pyfunc_op_equals(length, 1) || _pyfunc_op_equals(length, 2) || _pyfunc_op_equals(length, 4)");}
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
int_js_from_bytes = function flx_int_js_from_bytes (data, endianness) {
|
||||
var length;
|
||||
endianness = (endianness === undefined) ? "big": endianness;
|
||||
if (true) { /* if this_is_js() */
|
||||
if (!(_pyfunc_op_equals(endianness, "big"))) { throw _pyfunc_op_error('AssertionError', "_pyfunc_op_equals(endianness, \"big\")");}
|
||||
length = data.length;
|
||||
if (_pyfunc_op_equals(length, 1)) {
|
||||
return data[0];
|
||||
} else if (_pyfunc_op_equals(length, 2)) {
|
||||
return shl(data[0], 8) | data[1];
|
||||
} else if (_pyfunc_op_equals(length, 4)) {
|
||||
return ((shl(data[0], 24) | shl(data[1], 16)) | shl(data[2], 8)) | data[3];
|
||||
}
|
||||
if (!(_pyfunc_op_equals(length, 1) || _pyfunc_op_equals(length, 2) || _pyfunc_op_equals(length, 4))) { throw _pyfunc_op_error('AssertionError', "_pyfunc_op_equals(length, 1) || _pyfunc_op_equals(length, 2) || _pyfunc_op_equals(length, 4)");}
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
KonamiMRand = function () {
|
||||
_pyfunc_op_instantiate(this, arguments);
|
||||
}
|
||||
KonamiMRand.prototype._base_class = Object;
|
||||
KonamiMRand.prototype.__name__ = "KonamiMRand";
|
||||
|
||||
KonamiMRand.prototype.__init__ = function () {
|
||||
this.x = _pyfunc_op_mult([0], 522);
|
||||
return null;
|
||||
};
|
||||
|
||||
KonamiMRand.prototype.irnd = function (max) {
|
||||
var ret;
|
||||
max = (max === undefined) ? null: max;
|
||||
this.jrnd += 1;
|
||||
if ((this.jrnd >= 521)) {
|
||||
this.rnd521();
|
||||
this.jrnd = 0;
|
||||
}
|
||||
ret = this.x[this.jrnd];
|
||||
if ((max !== null)) {
|
||||
ret = safe_modulo(ret, max);
|
||||
}
|
||||
return ret;
|
||||
};
|
||||
|
||||
KonamiMRand.prototype.rnd521 = function () {
|
||||
var i;
|
||||
for (i = 0; i < 32; i += 1) {
|
||||
this.x[i] ^= this.x[i + 489];
|
||||
}
|
||||
for (i = 32; i < 521; i += 1) {
|
||||
this.x[i] ^= this.x[i - 32];
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
KonamiMRand.prototype.init_rnd = function (seed) {
|
||||
var _, bits, i, j, u;
|
||||
this.x = _pyfunc_op_mult([0], 522);
|
||||
for (i = 0; i < 16 + 1; i += 1) {
|
||||
bits = _pyfunc_op_mult([0], 32);
|
||||
for (j = 0; j < 32; j += 1) {
|
||||
seed = mul64(seed, 1566083941) + 1;
|
||||
bits[j] = ((!_pyfunc_op_equals((seed & 2147483648), 0)))? (1) : (0);
|
||||
}
|
||||
u = 0;
|
||||
for (j = 0; j < 32; j += 1) {
|
||||
u |= shl(bits[j], j);
|
||||
}
|
||||
this.x[i] = u & 4294967295;
|
||||
}
|
||||
this.x[16] = (shl(this.x[16], 23) ^ shr(this.x[0], 9)) ^ this.x[15];
|
||||
for (i = 17; i < 521; i += 1) {
|
||||
this.x[i] = (shl(this.x[i - 17], 23) ^ shr(this.x[i - 16], 9)) ^ this.x[i - 1];
|
||||
}
|
||||
for (_ = 0; _ < 9; _ += 1) {
|
||||
this.rnd521();
|
||||
}
|
||||
this.jrnd = 520;
|
||||
return null;
|
||||
};
|
||||
|
||||
|
||||
EuromixIRPassword = function () {
|
||||
_pyfunc_op_instantiate(this, arguments);
|
||||
}
|
||||
EuromixIRPassword.prototype._base_class = Object;
|
||||
EuromixIRPassword.prototype.__name__ = "EuromixIRPassword";
|
||||
|
||||
EuromixIRPassword.prototype.__init__ = function (machine_key) {
|
||||
this.machine_key = machine_key;
|
||||
this.prng = new KonamiMRand();
|
||||
this.parse_machine_key();
|
||||
return null;
|
||||
};
|
||||
|
||||
EuromixIRPassword.prototype.parse_machine_key = function () {
|
||||
var a, a1, a2, buf, chunk1, chunk1_data, chunk2, chunk2_data, chunk3, chunk3_data, day, machine_key, month, seed, stub2_, stub2_c, stub2_i0, stub2_iter0, v1, v2, year;
|
||||
stub2_ = [];stub2_iter0 = _pymeth_replace.call(this.machine_key, "-", "");if ((typeof stub2_iter0 === "object") && (!Array.isArray(stub2_iter0))) {stub2_iter0 = Object.keys(stub2_iter0);}for (stub2_i0=0; stub2_i0<stub2_iter0.length; stub2_i0++) {stub2_c = stub2_iter0[stub2_i0];{stub2_.push(stub2_c.charCodeAt(0));}}
|
||||
machine_key = stub2_;
|
||||
chunk1 = machine_key.slice(0,7);
|
||||
chunk2 = machine_key.slice(7,14);
|
||||
chunk3 = machine_key.slice(14,21);
|
||||
seed = this.generate_seed_hash("SIDENC", "GN894EAA");
|
||||
chunk1_data = this.decode_chunk(this.generate_scrambled_charset(seed), chunk1);
|
||||
chunk2_data = this.decode_chunk(this.generate_scrambled_charset(seed + 576), chunk2);
|
||||
a = this.decode_chunk(this.generate_scrambled_charset(seed + 1152), chunk3);
|
||||
chunk3_data = this.scramble_buffer_with_seed2(this.calc_crc16_alt(chunk2), int_js_to_bytes(a, 4));
|
||||
seed = this.generate_seed_hash("GN894EAA", "SIDENC");
|
||||
chunk3_data ^= seed;
|
||||
v1 = shr(chunk3_data, 8) & 255;
|
||||
v2 = chunk3_data & 255;
|
||||
this.prng.init_rnd((shl(v1, 8) | v2) | (shl(shl(v2, 8) | v1, 16)));
|
||||
chunk2_data ^= this.prng.irnd();
|
||||
chunk1_data ^= this.prng.irnd();
|
||||
buf = _pyfunc_list((_pyfunc_op_add((_pyfunc_op_add(int_js_to_bytes(chunk1_data, 4), int_js_to_bytes(chunk2_data, 4))), int_js_to_bytes(chunk3_data, 4))));
|
||||
a1 = this.calc_crc16_alt(buf, 4) & 255;
|
||||
a2 = this.calc_crc16(buf, 10) & 255;
|
||||
if ((((!_pyfunc_op_equals(a1, buf[10]))) || (!_pyfunc_op_equals(a2, buf[11])))) {
|
||||
console.log("Invalid checksums!");
|
||||
console.log((_pymeth_join.call(" ", ((function list_comprehension (iter0) {var res = [];var x, i0;if ((typeof iter0 === "object") && (!Array.isArray(iter0))) {iter0 = Object.keys(iter0);}for (i0=0; i0<iter0.length; i0++) {x = iter0[i0];{res.push(_pymeth_format.call("{:02X}", x));}}return res;}).call(this, buf)))));
|
||||
exit(1);
|
||||
}
|
||||
this.security_id = _pymeth_join.call("", ((function list_comprehension (iter0) {var res = [];var x, i0;if ((typeof iter0 === "object") && (!Array.isArray(iter0))) {iter0 = Object.keys(iter0);}for (i0=0; i0<iter0.length; i0++) {x = iter0[i0];{res.push(n2h(x));}}return res;}).call(this, buf.slice(4,10))));
|
||||
day = shr(chunk1_data, 11) & 31;
|
||||
month = shr(chunk1_data, 16) & 15;
|
||||
year = Math.floor(chunk1_data/1048576);
|
||||
console.log(_pymeth_format.call("{:d}/{:d}/{:d}", year, month, day) + " " + this.security_id);
|
||||
return _pyfunc_op_add(_pyfunc_op_add(chunk1, chunk2), chunk3);
|
||||
};
|
||||
|
||||
EuromixIRPassword.prototype.create_machine_key = function (security_id, year, month, day) {
|
||||
var buf, chunk1, chunk2, chunk3, payload, seed, t1, t2, v1, v2;
|
||||
payload = ((_pyfunc_op_mult(year, 1048576) | shl(month & 15, 16)) | shl(day & 31, 11)) | 798;
|
||||
buf = _pyfunc_op_add(int_js_to_bytes(payload, 4), security_id);
|
||||
v1 = this.calc_crc16_alt(buf, 4) & 255;
|
||||
buf = _pyfunc_op_add(buf, int_js_to_bytes(v1, 1));
|
||||
v2 = this.calc_crc16(buf, 10) & 255;
|
||||
buf = _pyfunc_op_add(buf, int_js_to_bytes(v2, 1));
|
||||
seed = this.generate_seed_hash("GN894EAA", "SIDENC");
|
||||
this.prng.init_rnd((shl(v1, 8) | v2) | (shl(shl(v2, 8) | v1, 16)));
|
||||
t1 = this.prng.irnd();
|
||||
t2 = this.prng.irnd();
|
||||
buf = this.xor_bytes(buf, 0, t2);
|
||||
buf = this.xor_bytes(buf, 4, t1);
|
||||
buf = this.xor_bytes(buf, 8, seed);
|
||||
seed = this.generate_seed_hash("SIDENC", "GN894EAA");
|
||||
chunk1 = this.encode_chunk(this.generate_scrambled_charset(seed), int_js_from_bytes(buf.slice(0,4)));
|
||||
chunk2 = this.encode_chunk(this.generate_scrambled_charset(seed + 576), int_js_from_bytes(buf.slice(4,8)));
|
||||
chunk3 = this.encode_chunk(this.generate_scrambled_charset(seed + 1152), this.scramble_buffer_with_seed2(this.calc_crc16_alt(chunk2), buf.slice(8,12)));
|
||||
return _pyfunc_op_add(_pyfunc_op_add(chunk1, chunk2), chunk3);
|
||||
};
|
||||
|
||||
EuromixIRPassword.prototype.scramble_buffer_with_seed2 = function (seed, data) {
|
||||
var bVar1, bVar2, data_idx, i, output, uVar4, uVar5, uVar6;
|
||||
output = this.scramble_buffer_with_seed(seed);
|
||||
for (i = 0; i < 16; i += 1) {
|
||||
uVar6 = 3 - shr(output[i], 3);
|
||||
uVar4 = output[i] & 7;
|
||||
uVar5 = output[i + 16] & 7;
|
||||
bVar2 = shl(1, uVar5) & 255;
|
||||
data_idx = (3 - shr(output[i + 16], 3)) & 255;
|
||||
bVar1 = data[data_idx];
|
||||
if ((_pyfunc_op_equals((shr(data[uVar6 & 255], uVar4) & 1), 0))) {
|
||||
data[data_idx] &= ~bVar2;
|
||||
} else {
|
||||
data[data_idx] |= bVar2;
|
||||
}
|
||||
uVar6 &= 255;
|
||||
if ((_pyfunc_op_equals((shr(bVar1, uVar5) & 1), 0))) {
|
||||
data[uVar6] &= ~shl(1, uVar4);
|
||||
} else {
|
||||
data[uVar6] |= shl(1, uVar4);
|
||||
}
|
||||
}
|
||||
return int_js_from_bytes(data) & 4294967295;
|
||||
};
|
||||
|
||||
EuromixIRPassword.prototype.generate_seed_hash = function (input, input2) {
|
||||
var a, b, c, hash1, iVar3, j, output, sra, stub3_, stub3_c, stub3_i0, stub3_iter0, stub4_, stub4_c, stub4_i0, stub4_iter0, stub5_seq, stub6_itr, stub7_seq, stub8_itr, uVar7;
|
||||
sra = (function flx_sra (x, n, m) {
|
||||
var filler;
|
||||
if ((!_pyfunc_op_equals((x & (Math.pow(2, (n - 1)))), 0))) {
|
||||
filler = _pyfunc_int((_pyfunc_op_add(_pyfunc_op_mult("1", m), (_pyfunc_op_mult("0", (n - m))))), 2);
|
||||
x = shr(x, m) | filler;
|
||||
return x;
|
||||
} else {
|
||||
return shr(x, m);
|
||||
}
|
||||
return null;
|
||||
}).bind(this);
|
||||
|
||||
stub3_ = [];stub3_iter0 = input;if ((typeof stub3_iter0 === "object") && (!Array.isArray(stub3_iter0))) {stub3_iter0 = Object.keys(stub3_iter0);}for (stub3_i0=0; stub3_i0<stub3_iter0.length; stub3_i0++) {stub3_c = stub3_iter0[stub3_i0];{stub3_.push(stub3_c.charCodeAt(0));}}
|
||||
input = stub3_;
|
||||
stub4_ = [];stub4_iter0 = input2;if ((typeof stub4_iter0 === "object") && (!Array.isArray(stub4_iter0))) {stub4_iter0 = Object.keys(stub4_iter0);}for (stub4_i0=0; stub4_i0<stub4_iter0.length; stub4_i0++) {stub4_c = stub4_iter0[stub4_i0];{stub4_.push(stub4_c.charCodeAt(0));}}
|
||||
input2 = stub4_;
|
||||
hash1 = 0;
|
||||
stub5_seq = input2;
|
||||
if ((typeof stub5_seq === "object") && (!Array.isArray(stub5_seq))) { stub5_seq = Object.keys(stub5_seq);}
|
||||
for (stub6_itr = 0; stub6_itr < stub5_seq.length; stub6_itr += 1) {
|
||||
c = stub5_seq[stub6_itr];
|
||||
for (j = 0; j < 6; j += 1) {
|
||||
a = (shl(hash1, 1) & 4294967295) | (sra(c, 8, j & 31) & 1);
|
||||
a &= 4294967295;
|
||||
b = sra(hash1, 32, 31) & 79764919;
|
||||
b &= 4294967295;
|
||||
hash1 = a ^ b;
|
||||
}
|
||||
}
|
||||
output = 0;
|
||||
stub7_seq = input;
|
||||
if ((typeof stub7_seq === "object") && (!Array.isArray(stub7_seq))) { stub7_seq = Object.keys(stub7_seq);}
|
||||
for (stub8_itr = 0; stub8_itr < stub7_seq.length; stub8_itr += 1) {
|
||||
c = stub7_seq[stub8_itr];
|
||||
iVar3 = c + 10685573;
|
||||
hash1 = mul64(hash1, iVar3);
|
||||
uVar7 = mul64(hash1, iVar3);
|
||||
output = _pyfunc_op_add(output, (hash1 & 4294901760) | (shr(uVar7, 15) & 65535));
|
||||
output &= 4294967295;
|
||||
hash1 = _pyfunc_op_add(uVar7, c) & 4294967295;
|
||||
}
|
||||
return output & 4294967295;
|
||||
};
|
||||
|
||||
EuromixIRPassword.prototype.generate_scrambled_charset = function (seed) {
|
||||
var _, charset, i1, i2, stub10_, stub9_, stub9_c, stub9_i0, stub9_iter0;
|
||||
this.prng.init_rnd(seed);
|
||||
stub9_ = [];stub9_iter0 = "123456789ABCDEFGHIJKLMNPQRSTUWXZ";if ((typeof stub9_iter0 === "object") && (!Array.isArray(stub9_iter0))) {stub9_iter0 = Object.keys(stub9_iter0);}for (stub9_i0=0; stub9_i0<stub9_iter0.length; stub9_i0++) {stub9_c = stub9_iter0[stub9_i0];{stub9_.push(stub9_c.charCodeAt(0));}}
|
||||
charset = stub9_;
|
||||
for (_ = 0; _ < 573; _ += 1) {
|
||||
i1 = this.prng.irnd(charset.length);
|
||||
i2 = this.prng.irnd(charset.length);
|
||||
stub10_ = [charset[i2], charset[i1]];
|
||||
charset[i1] = stub10_[0];charset[i2] = stub10_[1];
|
||||
}
|
||||
return charset;
|
||||
};
|
||||
|
||||
EuromixIRPassword.prototype.encode_chunk = function (charset, chunk, param2, chunkLen) {
|
||||
var _, c, output;
|
||||
param2 = (param2 === undefined) ? 32: param2;
|
||||
chunkLen = (chunkLen === undefined) ? 7: chunkLen;
|
||||
output = [];
|
||||
for (_ = 0; _ < chunkLen; _ += 1) {
|
||||
c = safe_modulo(chunk, param2);
|
||||
chunk = safe_div(chunk, param2);
|
||||
_pymeth_append.call(output, charset[c]);
|
||||
}
|
||||
return _pyfunc_list(output);
|
||||
};
|
||||
|
||||
EuromixIRPassword.prototype.decode_chunk = function (charset, chunk, param2, chunkLen) {
|
||||
var c, charsetIdx, chunkIdx, i, lastCharMaxIdx, output, stub11_seq, stub12_itr, stub13_tgt, t;
|
||||
param2 = (param2 === undefined) ? 32: param2;
|
||||
chunkLen = (chunkLen === undefined) ? 7: chunkLen;
|
||||
lastCharMaxIdx = 0;
|
||||
chunkIdx = 0;
|
||||
t = 4294967295;
|
||||
while (true) {
|
||||
if (_pyfunc_op_equals(t, 0)) {
|
||||
break;
|
||||
}
|
||||
lastCharMaxIdx = safe_modulo(t, param2);
|
||||
t = safe_div(t, param2);
|
||||
chunkIdx += 1;
|
||||
if ((chunkIdx >= chunkLen)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
output = 0;
|
||||
stub11_seq = _pyfunc_enumerate(chunk);
|
||||
if ((typeof stub11_seq === "object") && (!Array.isArray(stub11_seq))) { stub11_seq = Object.keys(stub11_seq);}
|
||||
for (stub12_itr = 0; stub12_itr < stub11_seq.length; stub12_itr += 1) {
|
||||
stub13_tgt = stub11_seq[stub12_itr];
|
||||
i = stub13_tgt[0]; c = stub13_tgt[1];
|
||||
charsetIdx = _pymeth_index.call(charset, c);
|
||||
output = _pyfunc_op_add(output, _pyfunc_op_mult(charsetIdx, Math.pow(param2, i)));
|
||||
}
|
||||
if ((((((!_pyfunc_op_equals(chunkIdx, chunk.length))) || (charsetIdx <= lastCharMaxIdx))) && (output <= 4294967295))) {
|
||||
return output;
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
EuromixIRPassword.prototype.scramble_buffer_with_seed = function (seed) {
|
||||
var _, d, i, j, output, stub14_, t1, t2, v;
|
||||
this.prng.init_rnd(seed);
|
||||
d = [];
|
||||
for (i = 0; i < 32; i += 2) {
|
||||
_pymeth_append.call(d, i);
|
||||
}
|
||||
for (i = 1; i < 32; i += 2) {
|
||||
_pymeth_append.call(d, i);
|
||||
}
|
||||
output = _pyfunc_op_mult([0], d.length);
|
||||
for (i = 0; i < Math.floor(output.length/2); i += 1) {
|
||||
v = this.prng.irnd();
|
||||
if ((_pyfunc_op_equals((v & 1), 0))) {
|
||||
output[i] = d[i];
|
||||
output[i + 16] = d[i + 16];
|
||||
} else {
|
||||
output[i] = d[i + 16];
|
||||
output[i + 16] = d[i];
|
||||
}
|
||||
}
|
||||
for (j = 0; j < 2; j += 1) {
|
||||
for (_ = 0; _ < 576; _ += 1) {
|
||||
t1 = this.prng.irnd() & 15;
|
||||
t2 = this.prng.irnd() & 15;
|
||||
stub14_ = [output[_pyfunc_op_add(t2, _pyfunc_op_mult(j, 16))], output[_pyfunc_op_add(t1, _pyfunc_op_mult(j, 16))]];
|
||||
output[_pyfunc_op_add(t1, _pyfunc_op_mult(j, 16))] = stub14_[0];output[_pyfunc_op_add(t2, _pyfunc_op_mult(j, 16))] = stub14_[1];
|
||||
}
|
||||
}
|
||||
return output;
|
||||
};
|
||||
|
||||
EuromixIRPassword.prototype.scramble_buffer_with_seed_even_more = function (seed, data) {
|
||||
var i, output, uVar2, uVar3;
|
||||
output = this.scramble_buffer_with_seed(seed);
|
||||
for (i = 0; i < 16; i += 1) {
|
||||
uVar3 = data;
|
||||
if ((_pyfunc_op_equals((uVar3 & shl(1, output[i] & 31)), 0))) {
|
||||
uVar2 = uVar3 & (~shl(1, output[i + 16] & 31));
|
||||
} else {
|
||||
uVar2 = uVar3 | shl(1, output[i + 16] & 31);
|
||||
}
|
||||
data = uVar2;
|
||||
if ((_pyfunc_op_equals((uVar3 & shl(1, output[i + 16] & 31)), 0))) {
|
||||
uVar3 = data & (~shl(1, output[i] & 31));
|
||||
} else {
|
||||
uVar3 = data | shl(1, output[i] & 31);
|
||||
}
|
||||
data = uVar3;
|
||||
}
|
||||
return data;
|
||||
};
|
||||
|
||||
EuromixIRPassword.prototype.calc_crc16 = function (data, length) {
|
||||
var _, crc, i;
|
||||
length = (length === undefined) ? null: length;
|
||||
crc = 65535;
|
||||
if ((length === null)) {
|
||||
length = data.length;
|
||||
}
|
||||
for (i = 0; i < length; i += 1) {
|
||||
crc ^= shl(data[i], 8);
|
||||
for (_ = 0; _ < 8; _ += 1) {
|
||||
crc = shl(crc, 1) ^ (((!_pyfunc_op_equals((crc & 32768), 0)))? (4129) : (0));
|
||||
}
|
||||
}
|
||||
return (~crc) & 65535;
|
||||
};
|
||||
|
||||
EuromixIRPassword.prototype.calc_crc16_alt = function (data, length) {
|
||||
var _, crc, i;
|
||||
length = (length === undefined) ? null: length;
|
||||
crc = 65535;
|
||||
if ((length === null)) {
|
||||
length = data.length;
|
||||
}
|
||||
for (i = 0; i < length; i += 1) {
|
||||
crc ^= data[i];
|
||||
for (_ = 0; _ < 8; _ += 1) {
|
||||
crc = shr(crc, 1) ^ (((!_pyfunc_op_equals((crc & 1), 0)))? (33800) : (0));
|
||||
}
|
||||
}
|
||||
return crc & 65535;
|
||||
};
|
||||
|
||||
EuromixIRPassword.prototype.xor_bytes = function (data, offset, val) {
|
||||
var result;
|
||||
result = int_js_to_bytes((int_js_from_bytes(data.slice(offset,offset + 4))) ^ val, 4);
|
||||
return _pyfunc_op_add((_pyfunc_op_add((_pyfunc_list(data.slice(0,offset))), _pyfunc_list(result))), (_pyfunc_list(data.slice(offset + 4))));
|
||||
};
|
||||
|
||||
EuromixIRPassword.prototype.verify_password = function (password) {
|
||||
var buf, chunk1, chunk1_output, chunk2, chunk2_output, chunk3, chunk3_output, h1, h2, h3, h4, seed, stub15_, stub16_, stub16_i, stub16_i0, stub16_iter0, v, x;
|
||||
this.prng = new KonamiMRand();
|
||||
password = ((password !== null))? ((function list_comprehension (iter0) {var res = [];var c, i0;if ((typeof iter0 === "object") && (!Array.isArray(iter0))) {iter0 = Object.keys(iter0);}for (i0=0; i0<iter0.length; i0++) {c = iter0[i0];{res.push(c.charCodeAt(0));}}return res;}).call(this, _pymeth_replace.call(password, "-", ""))) : (null);
|
||||
stub16_ = [];stub16_iter0 = _pyfunc_range(0, password.length, 7);if ((typeof stub16_iter0 === "object") && (!Array.isArray(stub16_iter0))) {stub16_iter0 = Object.keys(stub16_iter0);}for (stub16_i0=0; stub16_i0<stub16_iter0.length; stub16_i0++) {stub16_i = stub16_iter0[stub16_i0];{stub16_.push(password.slice(stub16_i,stub16_i + 7));}}
|
||||
stub15_ = stub16_;
|
||||
chunk1 = stub15_[0];chunk2 = stub15_[1];chunk3 = stub15_[2];
|
||||
seed = this.generate_seed_hash(this.security_id, "GN894EAA");
|
||||
x = this.decode_chunk(this.generate_scrambled_charset(seed), chunk1);
|
||||
console.log(x);
|
||||
chunk1_output = this.scramble_buffer_with_seed_even_more(seed + 897, x);
|
||||
chunk2_output = this.scramble_buffer_with_seed_even_more(this.calc_crc16(chunk1), this.decode_chunk(this.generate_scrambled_charset(seed + 576), chunk2));
|
||||
chunk3_output = this.scramble_buffer_with_seed_even_more(this.calc_crc16_alt(chunk2), this.decode_chunk(this.generate_scrambled_charset(seed + 1152), chunk3));
|
||||
buf = _pyfunc_list((_pyfunc_op_add((_pyfunc_op_add(int_js_to_bytes(chunk1_output, 4), int_js_to_bytes(chunk2_output, 4))), int_js_to_bytes(chunk3_output, 4))));
|
||||
seed = this.generate_seed_hash("GN894EAA", this.security_id);
|
||||
this.prng.init_rnd(seed);
|
||||
buf = this.xor_bytes(buf, 8, this.prng.irnd());
|
||||
this.prng.init_rnd(int_js_from_bytes(buf.slice(8,12)));
|
||||
buf = this.xor_bytes(buf, 0, this.prng.irnd());
|
||||
buf = this.xor_bytes(buf, 4, this.prng.irnd());
|
||||
h1 = _pyfunc_op_equals(this.calc_crc16(buf, 8), (int_js_from_bytes(buf.slice(8,10))));
|
||||
if ((!_pyfunc_op_equals(h1, true))) {
|
||||
return false;
|
||||
}
|
||||
h2 = _pyfunc_op_equals(this.calc_crc16_alt(buf, 10), (int_js_from_bytes(buf.slice(10,12))));
|
||||
if ((!_pyfunc_op_equals(h2, true))) {
|
||||
return false;
|
||||
}
|
||||
buf = this.xor_bytes(buf, 4, seed);
|
||||
v = this.generate_seed_hash(this.security_id, n2h_long(int_js_from_bytes(buf.slice(4,8))));
|
||||
buf = this.xor_bytes(buf, 0, v);
|
||||
h3 = _pyfunc_op_equals(this.calc_crc16(buf, 4), (int_js_from_bytes(buf.slice(4,6))));
|
||||
if ((!_pyfunc_op_equals(h3, true))) {
|
||||
return false;
|
||||
}
|
||||
h4 = _pyfunc_op_equals(this.calc_crc16_alt(buf, 6), (int_js_from_bytes(buf.slice(6,8))));
|
||||
if ((!_pyfunc_op_equals(h4, true))) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
EuromixIRPassword.prototype.generate_password = function (year, month, day) {
|
||||
var buf, chunk1, chunk1_payload, chunk2, chunk2_payload, chunk3, chunk3_payload, h1, h2, parts, payload, seed, stub17_seq, stub18_itr, x;
|
||||
if (!(year > 2000)) { throw _pyfunc_op_error('AssertionError', "year > 2000");}
|
||||
if (!(month > 8)) { throw _pyfunc_op_error('AssertionError', "month > 8");}
|
||||
payload = (day | shl(month, 8)) | shl(year, 16);
|
||||
buf = int_js_to_bytes(payload, 4);
|
||||
buf = _pyfunc_op_add(buf, int_js_to_bytes(this.calc_crc16(buf, 4), 2));
|
||||
buf = _pyfunc_op_add(buf, int_js_to_bytes(this.calc_crc16_alt(buf, 6), 2));
|
||||
seed = this.generate_seed_hash(this.security_id, n2h_long(int_js_from_bytes(buf.slice(4,8))));
|
||||
buf = this.xor_bytes(buf, 0, seed);
|
||||
seed = this.generate_seed_hash("GN894EAA", this.security_id);
|
||||
buf = this.xor_bytes(buf, 4, seed);
|
||||
buf = _pyfunc_op_add(buf, int_js_to_bytes(this.calc_crc16(buf, 8), 2));
|
||||
buf = _pyfunc_op_add(buf, int_js_to_bytes(this.calc_crc16_alt(buf, 10), 2));
|
||||
h1 = _pyfunc_op_equals(this.calc_crc16(buf, 8), (int_js_from_bytes(buf.slice(8,10))));
|
||||
if ((!_pyfunc_op_equals(h1, true))) {
|
||||
return false;
|
||||
}
|
||||
h2 = _pyfunc_op_equals(this.calc_crc16_alt(buf, 10), (int_js_from_bytes(buf.slice(10,12))));
|
||||
if ((!_pyfunc_op_equals(h2, true))) {
|
||||
return false;
|
||||
}
|
||||
chunk1_payload = int_js_from_bytes(buf.slice(0,4));
|
||||
chunk2_payload = int_js_from_bytes(buf.slice(4,8));
|
||||
chunk3_payload = int_js_from_bytes(buf.slice(8,12));
|
||||
seed = this.generate_seed_hash("GN894EAA", this.security_id);
|
||||
this.prng.init_rnd(seed);
|
||||
chunk3_payload ^= this.prng.irnd();
|
||||
this.prng.init_rnd(int_js_from_bytes(buf.slice(8,12)));
|
||||
chunk1_payload ^= this.prng.irnd();
|
||||
chunk2_payload ^= this.prng.irnd();
|
||||
seed = this.generate_seed_hash(this.security_id, "GN894EAA");
|
||||
chunk1 = this.encode_chunk(this.generate_scrambled_charset(seed), this.scramble_buffer_with_seed_even_more(seed + 897, chunk1_payload));
|
||||
chunk2 = this.encode_chunk(this.generate_scrambled_charset(seed + 576), this.scramble_buffer_with_seed_even_more(this.calc_crc16(chunk1), chunk2_payload));
|
||||
chunk3 = this.encode_chunk(this.generate_scrambled_charset(seed + 1152), this.scramble_buffer_with_seed_even_more(this.calc_crc16_alt(chunk2), chunk3_payload));
|
||||
parts = [];
|
||||
stub17_seq = [chunk1, chunk2, chunk3];
|
||||
if ((typeof stub17_seq === "object") && (!Array.isArray(stub17_seq))) { stub17_seq = Object.keys(stub17_seq);}
|
||||
for (stub18_itr = 0; stub18_itr < stub17_seq.length; stub18_itr += 1) {
|
||||
x = stub17_seq[stub18_itr];
|
||||
_pymeth_append.call(parts, (_pymeth_join.call("", ((function list_comprehension (iter0) {var res = [];var c, i0;if ((typeof iter0 === "object") && (!Array.isArray(iter0))) {iter0 = Object.keys(iter0);}for (i0=0; i0<iter0.length; i0++) {c = iter0[i0];{res.push(String.fromCharCode(c));}}return res;}).call(this, x)))));
|
||||
}
|
||||
return _pymeth_join.call("-", parts);
|
||||
};
|
||||
|
||||
|
||||
generate_password = function flx_generate_password (machine_license_key, year, day, month) {
|
||||
var irpass, irpass_check, password;
|
||||
year = (year === undefined) ? 3030: year;
|
||||
day = (day === undefined) ? 9: day;
|
||||
month = (month === undefined) ? 22: month;
|
||||
irpass = new EuromixIRPassword(machine_license_key);
|
||||
password = irpass.generate_password(year, day, month);
|
||||
irpass_check = new EuromixIRPassword(machine_license_key);
|
||||
if ((_pyfunc_op_equals(irpass_check.verify_password(password), false))) {
|
||||
return "Failed to generate password!";
|
||||
}
|
||||
return password;
|
||||
};
|
|
@ -0,0 +1,666 @@
|
|||
# Lots of hacks for pscript so the website can be generated using the same Python code
|
||||
|
||||
def this_is_js():
|
||||
return False
|
||||
|
||||
|
||||
def safe_modulo(n, m):
|
||||
if this_is_js() and n < 0:
|
||||
# For pscript/Javascript
|
||||
return ((n % m) + m) % m
|
||||
|
||||
return n % m
|
||||
|
||||
|
||||
def n2h(a):
|
||||
if this_is_js():
|
||||
h = "0123456789abcdef"
|
||||
a1 = a % 16
|
||||
a2 = a // 16
|
||||
return h[a2] + h[a1]
|
||||
|
||||
return "%02x" % a
|
||||
|
||||
|
||||
def n2h_long(a):
|
||||
if this_is_js():
|
||||
h = "0123456789abcdef"
|
||||
ret = []
|
||||
while a > 0:
|
||||
a1 = a % 16
|
||||
a = safe_div(a, 16)
|
||||
ret = [h[a1]] + ret
|
||||
|
||||
return "".join(ret)
|
||||
|
||||
return "%x" % a
|
||||
|
||||
|
||||
def shr(a, n):
|
||||
if this_is_js():
|
||||
a &= 0xffffffff
|
||||
|
||||
bits = [1 if (a & (1 << i)) != 0 else 0 for i in range(32)][n:]
|
||||
|
||||
output = 0
|
||||
for i in range(min(len(bits), 32)):
|
||||
output |= bits[i] << i
|
||||
|
||||
return output
|
||||
|
||||
return (a >> n) & 0xffffffff
|
||||
|
||||
|
||||
def shl(a, n):
|
||||
if this_is_js():
|
||||
a &= 0xffffffff
|
||||
|
||||
bits = [1 if (a & (1 << i)) != 0 else 0 for i in range(32)]
|
||||
|
||||
output = 0
|
||||
for i in range(min(n, 32), 32):
|
||||
output |= bits[i-n] << i
|
||||
|
||||
return output
|
||||
|
||||
return (a << n) & 0xffffffff
|
||||
|
||||
|
||||
def mul64(a, b):
|
||||
if this_is_js():
|
||||
al = a & 0xffff
|
||||
ah = shr(a, 16)
|
||||
|
||||
bl = b & 0xffff
|
||||
bh = shr(b, 16)
|
||||
|
||||
rl = al * bl
|
||||
rm1 = ah * bl
|
||||
rm2 = al * bh
|
||||
|
||||
rm1l = rm1 & 0xffff
|
||||
rm2l = rm2 & 0xffff
|
||||
rml = (rm1l + rm2l) & 0xffff
|
||||
|
||||
rl += shl(rml, 16)
|
||||
|
||||
return rl
|
||||
|
||||
return (a * b) & 0xffffffff
|
||||
|
||||
|
||||
def safe_div(n, m):
|
||||
if this_is_js():
|
||||
if (m & (m - 1) == 0) and m != 0:
|
||||
# Is power of two
|
||||
for i in range(32):
|
||||
if (2 ** i) == m:
|
||||
return shr(n, i)
|
||||
|
||||
# Pray
|
||||
return n // m
|
||||
|
||||
return n // m
|
||||
|
||||
|
||||
def int_js_to_bytes(data, length, endianness="big"):
|
||||
if this_is_js():
|
||||
assert(endianness == "big")
|
||||
|
||||
if length == 1:
|
||||
return data[0]
|
||||
|
||||
elif length == 2:
|
||||
return [shr(data, 8) & 0xff, data & 0xff]
|
||||
|
||||
elif length == 4:
|
||||
return [shr(data, 24) & 0xff, shr(data, 16) & 0xff, shr(data, 8) & 0xff, data & 0xff]
|
||||
|
||||
assert(length == 1 or length == 2 or length == 4)
|
||||
|
||||
else:
|
||||
return list(int.to_bytes(data, length, endianness))
|
||||
|
||||
def int_js_from_bytes(data, endianness="big"):
|
||||
if this_is_js():
|
||||
assert(endianness == "big")
|
||||
|
||||
length = len(data)
|
||||
|
||||
if length == 1:
|
||||
return data[0]
|
||||
|
||||
elif length == 2:
|
||||
return shl(data[0], 8) | data[1]
|
||||
|
||||
elif length == 4:
|
||||
return shl(data[0], 24) | shl(data[1], 16) | shl(data[2], 8) | data[3]
|
||||
|
||||
assert(length == 1 or length == 2 or length == 4)
|
||||
|
||||
else:
|
||||
return int.from_bytes(data, endianness)
|
||||
|
||||
|
||||
class KonamiMRand:
|
||||
# mrnd.c from https://oku.edu.mie-u.ac.jp/~okumura/algo/archive/algo.tar.gz
|
||||
def __init__(self):
|
||||
self.x = [0] * 522
|
||||
|
||||
|
||||
def irnd(self, max=None):
|
||||
self.jrnd += 1
|
||||
|
||||
if self.jrnd >= 521:
|
||||
self.rnd521()
|
||||
self.jrnd = 0
|
||||
|
||||
ret = self.x[self.jrnd]
|
||||
if max is not None:
|
||||
ret = safe_modulo(ret, max)
|
||||
|
||||
return ret
|
||||
|
||||
|
||||
def rnd521(self):
|
||||
for i in range(32):
|
||||
self.x[i] ^= self.x[i + 489]
|
||||
|
||||
for i in range(32, 521):
|
||||
self.x[i] ^= self.x[i - 32]
|
||||
|
||||
|
||||
def init_rnd(self, seed):
|
||||
self.x = [0] * 522
|
||||
|
||||
for i in range(16 + 1):
|
||||
bits = [0] * 32
|
||||
for j in range(32):
|
||||
seed = mul64(seed, 0x5d588b65) + 1
|
||||
bits[j] = 1 if (seed & 0x80000000) != 0 else 0
|
||||
|
||||
u = 0
|
||||
for j in range(32):
|
||||
u |= shl(bits[j], j)
|
||||
|
||||
self.x[i] = u & 0xffffffff
|
||||
|
||||
self.x[16] = shl(self.x[16], 23) ^ shr(self.x[0], 9) ^ self.x[15]
|
||||
|
||||
for i in range(17, 521):
|
||||
self.x[i] = shl(self.x[i-17], 23) ^ shr(self.x[i-16], 9) ^ self.x[i-1]
|
||||
|
||||
for _ in range(9):
|
||||
self.rnd521()
|
||||
|
||||
self.jrnd = 520
|
||||
|
||||
|
||||
class EuromixIRPassword:
|
||||
def __init__(self, machine_key):
|
||||
self.machine_key = machine_key
|
||||
self.prng = KonamiMRand()
|
||||
self.parse_machine_key()
|
||||
|
||||
|
||||
def parse_machine_key(self):
|
||||
machine_key = [ord(c) for c in self.machine_key.replace("-", "")]
|
||||
chunk1 = machine_key[:7]
|
||||
chunk2 = machine_key[7:14]
|
||||
chunk3 = machine_key[14:21]
|
||||
|
||||
seed = self.generate_seed_hash("SIDENC", "GN894EAA")
|
||||
chunk1_data = self.decode_chunk(
|
||||
self.generate_scrambled_charset(seed),
|
||||
chunk1
|
||||
)
|
||||
|
||||
chunk2_data = self.decode_chunk(
|
||||
self.generate_scrambled_charset(seed + 0x240),
|
||||
chunk2
|
||||
)
|
||||
|
||||
a = self.decode_chunk(
|
||||
self.generate_scrambled_charset(seed + 0x480),
|
||||
chunk3
|
||||
)
|
||||
|
||||
chunk3_data = self.scramble_buffer_with_seed2(
|
||||
self.calc_crc16_alt(chunk2),
|
||||
int_js_to_bytes(a, 4)
|
||||
)
|
||||
|
||||
seed = self.generate_seed_hash("GN894EAA", "SIDENC")
|
||||
chunk3_data ^= seed
|
||||
|
||||
v1 = shr(chunk3_data, 8) & 0xff
|
||||
v2 = chunk3_data & 0xff
|
||||
self.prng.init_rnd(shl(v1, 8) | v2 | shl((shl(v2, 8) | v1), 16))
|
||||
|
||||
chunk2_data ^= self.prng.irnd()
|
||||
chunk1_data ^= self.prng.irnd()
|
||||
|
||||
buf = list(
|
||||
int_js_to_bytes(chunk1_data, 4)
|
||||
+ int_js_to_bytes(chunk2_data, 4)
|
||||
+ int_js_to_bytes(chunk3_data, 4)
|
||||
)
|
||||
|
||||
a1 = self.calc_crc16_alt(buf, 4) & 0xff
|
||||
a2 = self.calc_crc16(buf, 10) & 0xff
|
||||
|
||||
if a1 != buf[10] or a2 != buf[11]:
|
||||
print("Invalid checksums!")
|
||||
print(" ".join(["%02X" % x for x in buf]))
|
||||
exit(1)
|
||||
|
||||
self.security_id = "".join([n2h(x) for x in buf[4:10]])
|
||||
|
||||
day = shr(chunk1_data, 0x0b) & 0x1f
|
||||
month = shr(chunk1_data, 0x10) & 0x0f
|
||||
year = chunk1_data // 0x100000
|
||||
|
||||
print("%d/%d/%d" % (year, month, day), self.security_id)
|
||||
|
||||
return chunk1 + chunk2 + chunk3
|
||||
|
||||
|
||||
def create_machine_key(self, security_id, year, month, day):
|
||||
payload = year * 0x100000 | shl((month & 0x0f), 0x10) | shl((day & 0x1f), 0x0b) | 0x31e
|
||||
|
||||
buf = int_js_to_bytes(payload, 4) + security_id
|
||||
v1 = self.calc_crc16_alt(buf, 4) & 0xff
|
||||
buf += int_js_to_bytes(v1, 1)
|
||||
v2 = self.calc_crc16(buf, 10) & 0xff
|
||||
buf += int_js_to_bytes(v2, 1)
|
||||
|
||||
seed = self.generate_seed_hash("GN894EAA", "SIDENC")
|
||||
self.prng.init_rnd(shl(v1, 8) | v2 | shl((shl(v2, 8) | v1), 16))
|
||||
|
||||
t1 = self.prng.irnd()
|
||||
t2 = self.prng.irnd()
|
||||
buf = self.xor_bytes(buf, 0, t2)
|
||||
buf = self.xor_bytes(buf, 4, t1)
|
||||
buf = self.xor_bytes(buf, 8, seed)
|
||||
|
||||
seed = self.generate_seed_hash("SIDENC", "GN894EAA")
|
||||
chunk1 = self.encode_chunk(
|
||||
self.generate_scrambled_charset(seed),
|
||||
int_js_from_bytes(buf[:4])
|
||||
)
|
||||
|
||||
chunk2 = self.encode_chunk(
|
||||
self.generate_scrambled_charset(seed + 0x240),
|
||||
int_js_from_bytes(buf[4:8])
|
||||
)
|
||||
|
||||
chunk3 = self.encode_chunk(
|
||||
self.generate_scrambled_charset(seed + 0x480),
|
||||
self.scramble_buffer_with_seed2(
|
||||
self.calc_crc16_alt(chunk2),
|
||||
buf[8:12]
|
||||
)
|
||||
)
|
||||
|
||||
return chunk1 + chunk2 + chunk3
|
||||
|
||||
|
||||
def scramble_buffer_with_seed2(self, seed, data):
|
||||
output = self.scramble_buffer_with_seed(seed)
|
||||
|
||||
for i in range(16):
|
||||
uVar6 = 3 - shr(output[i], 3)
|
||||
uVar4 = output[i] & 7
|
||||
uVar5 = output[i + 16] & 7
|
||||
bVar2 = shl(1, uVar5) & 0xff
|
||||
|
||||
data_idx = 3 - shr(output[i + 16], 3) & 0xff
|
||||
bVar1 = data[data_idx]
|
||||
|
||||
if (shr(data[uVar6 & 0xff], uVar4) & 1) == 0:
|
||||
data[data_idx] &= ~bVar2
|
||||
else:
|
||||
data[data_idx] |= bVar2
|
||||
|
||||
uVar6 &= 0xff
|
||||
if (shr(bVar1, uVar5) & 1) == 0:
|
||||
data[uVar6] &= ~shl(1, uVar4)
|
||||
else:
|
||||
data[uVar6] |= shl(1, uVar4)
|
||||
|
||||
return int_js_from_bytes(data) & 0xffffffff
|
||||
|
||||
|
||||
def generate_seed_hash(self, input, input2):
|
||||
def sra(x, n, m):
|
||||
if x & 2 ** (n - 1) != 0:
|
||||
filler = int('1' * m + '0' * (n - m), 2)
|
||||
x = shr(x, m) | filler
|
||||
return x
|
||||
|
||||
else:
|
||||
return shr(x, m)
|
||||
|
||||
input = [ord(c) for c in input]
|
||||
input2 = [ord(c) for c in input2]
|
||||
|
||||
hash1 = 0
|
||||
for c in input2:
|
||||
for j in range(6):
|
||||
a = (((shl(hash1, 1) & 0xffffffff) | (sra(c, 8, j & 0x1f) & 1)))
|
||||
a &= 0xffffffff
|
||||
|
||||
b = (sra(hash1, 32, 0x1f) & 0x4c11db7)
|
||||
b &= 0xffffffff
|
||||
|
||||
hash1 = a ^ b
|
||||
|
||||
output = 0
|
||||
for c in input:
|
||||
iVar3 = c + 0xa30c85
|
||||
hash1 = mul64(hash1, iVar3)
|
||||
uVar7 = mul64(hash1, iVar3)
|
||||
output += (hash1 & 0xffff0000) | (shr(uVar7, 0x0f) & 0xffff)
|
||||
output &= 0xffffffff
|
||||
|
||||
hash1 = (uVar7 + c) & 0xffffffff
|
||||
|
||||
return output & 0xffffffff
|
||||
|
||||
|
||||
def generate_scrambled_charset(self, seed):
|
||||
self.prng.init_rnd(seed)
|
||||
charset = [ord(c) for c in "123456789ABCDEFGHIJKLMNPQRSTUWXZ"]
|
||||
for _ in range(0x23d):
|
||||
i1 = self.prng.irnd(len(charset))
|
||||
i2 = self.prng.irnd(len(charset))
|
||||
charset[i1], charset[i2] = charset[i2], charset[i1]
|
||||
|
||||
return charset
|
||||
|
||||
|
||||
def encode_chunk(self, charset, chunk, param2=32, chunkLen=7):
|
||||
output = []
|
||||
for _ in range(chunkLen):
|
||||
c = safe_modulo(chunk, param2)
|
||||
chunk = safe_div(chunk, param2)
|
||||
output.append(charset[c])
|
||||
|
||||
return list(output)
|
||||
|
||||
|
||||
def decode_chunk(self, charset, chunk, param2=32, chunkLen=7):
|
||||
lastCharMaxIdx = 0
|
||||
|
||||
# Is param2 ever not 32 and chunkLen ever not 7?
|
||||
chunkIdx = 0
|
||||
t = 0xffffffff
|
||||
while True:
|
||||
if t == 0:
|
||||
break
|
||||
|
||||
lastCharMaxIdx = safe_modulo(t, param2)
|
||||
t = safe_div(t, param2)
|
||||
|
||||
chunkIdx += 1
|
||||
if chunkIdx >= chunkLen:
|
||||
break
|
||||
|
||||
output = 0
|
||||
for i, c in enumerate(chunk):
|
||||
charsetIdx = charset.index(c)
|
||||
output += charsetIdx * (param2 ** i)
|
||||
|
||||
if (chunkIdx != len(chunk) or charsetIdx <= lastCharMaxIdx) and output <= 0xffffffff:
|
||||
return output
|
||||
|
||||
return None
|
||||
|
||||
|
||||
def scramble_buffer_with_seed(self, seed):
|
||||
self.prng.init_rnd(seed)
|
||||
|
||||
d = []
|
||||
for i in range(0, 0x20, 2):
|
||||
d.append(i)
|
||||
|
||||
for i in range(1, 0x20, 2):
|
||||
d.append(i)
|
||||
|
||||
output = [0] * len(d)
|
||||
for i in range(len(output) // 2):
|
||||
v = self.prng.irnd()
|
||||
|
||||
if (v & 1) == 0:
|
||||
output[i] = d[i]
|
||||
output[i+0x10] = d[i+0x10]
|
||||
else:
|
||||
output[i] = d[i+0x10]
|
||||
output[i+0x10] = d[i]
|
||||
|
||||
for j in range(2):
|
||||
for _ in range(0x240):
|
||||
t1 = self.prng.irnd() & 0x0f
|
||||
t2 = self.prng.irnd() & 0x0f
|
||||
output[t1 + j * 0x10], output[t2 + j * 0x10] = output[t2 + j * 0x10], output[t1 + j * 0x10]
|
||||
|
||||
return output
|
||||
|
||||
|
||||
def scramble_buffer_with_seed_even_more(self, seed, data):
|
||||
output = self.scramble_buffer_with_seed(seed)
|
||||
|
||||
for i in range(0x10):
|
||||
uVar3 = data
|
||||
if (uVar3 & shl(1, (output[i] & 0x1f))) == 0:
|
||||
uVar2 = uVar3 & ~shl(1, (output[i+0x10] & 0x1f))
|
||||
else:
|
||||
uVar2 = uVar3 | shl(1, (output[i+0x10] & 0x1f))
|
||||
data = uVar2
|
||||
|
||||
if (uVar3 & shl(1, (output[i+0x10] & 0x1f))) == 0:
|
||||
uVar3 = data & ~shl(1, (output[i] & 0x1f))
|
||||
else:
|
||||
uVar3 = data | shl(1, (output[i] & 0x1f))
|
||||
data = uVar3
|
||||
|
||||
return data
|
||||
|
||||
|
||||
def calc_crc16(self, data, length=None):
|
||||
crc = 0xffff
|
||||
|
||||
if length is None:
|
||||
length = len(data)
|
||||
|
||||
for i in range(length):
|
||||
crc ^= shl(data[i], 8)
|
||||
|
||||
for _ in range(8):
|
||||
crc = shl(crc, 1) ^ (0x1021 if (crc & 0x8000) != 0 else 0)
|
||||
|
||||
return ~crc & 0xffff
|
||||
|
||||
|
||||
def calc_crc16_alt(self, data, length=None):
|
||||
crc = 0xffff
|
||||
|
||||
if length is None:
|
||||
length = len(data)
|
||||
|
||||
for i in range(length):
|
||||
crc ^= data[i]
|
||||
|
||||
for _ in range(8):
|
||||
crc = shr(crc, 1) ^ (0x8408 if (crc & 1) != 0 else 0)
|
||||
|
||||
return crc & 0xffff
|
||||
|
||||
|
||||
def xor_bytes(self, data, offset, val):
|
||||
result = int_js_to_bytes(
|
||||
int_js_from_bytes(data[offset:offset+4]) ^ val,
|
||||
4
|
||||
)
|
||||
return list(data[:offset]) + list(result) + list(data[offset+4:])
|
||||
|
||||
|
||||
def verify_password(self, password):
|
||||
self.prng = KonamiMRand()
|
||||
|
||||
password = [ord(c) for c in password.replace("-", "")] if password is not None else None
|
||||
|
||||
chunk1, chunk2, chunk3 = [password[i:i+7] for i in range(0, len(password), 7)]
|
||||
|
||||
# Scramble the input password charset based on the game code + security cassette ID
|
||||
seed = self.generate_seed_hash(self.security_id, "GN894EAA")
|
||||
|
||||
x = self.decode_chunk(
|
||||
self.generate_scrambled_charset(seed),
|
||||
chunk1
|
||||
)
|
||||
print(x)
|
||||
chunk1_output = self.scramble_buffer_with_seed_even_more(
|
||||
seed + 0x381,
|
||||
x
|
||||
)
|
||||
|
||||
chunk2_output = self.scramble_buffer_with_seed_even_more(
|
||||
self.calc_crc16(chunk1),
|
||||
self.decode_chunk(
|
||||
self.generate_scrambled_charset(seed + 0x240),
|
||||
chunk2
|
||||
)
|
||||
)
|
||||
|
||||
chunk3_output = self.scramble_buffer_with_seed_even_more(
|
||||
self.calc_crc16_alt(chunk2),
|
||||
self.decode_chunk(
|
||||
self.generate_scrambled_charset(seed + 0x480),
|
||||
chunk3
|
||||
)
|
||||
)
|
||||
|
||||
buf = list(
|
||||
int_js_to_bytes(chunk1_output, 4)
|
||||
+ int_js_to_bytes(chunk2_output, 4)
|
||||
+ int_js_to_bytes(chunk3_output, 4)
|
||||
)
|
||||
|
||||
seed = self.generate_seed_hash("GN894EAA", self.security_id)
|
||||
self.prng.init_rnd(seed)
|
||||
buf = self.xor_bytes(buf, 8, self.prng.irnd())
|
||||
|
||||
self.prng.init_rnd(int_js_from_bytes(buf[8:12]))
|
||||
buf = self.xor_bytes(buf, 0, self.prng.irnd())
|
||||
buf = self.xor_bytes(buf, 4, self.prng.irnd())
|
||||
|
||||
h1 = self.calc_crc16(buf, 8) == int_js_from_bytes(buf[8:10])
|
||||
if h1 != True:
|
||||
return False
|
||||
|
||||
h2 = self.calc_crc16_alt(buf, 10) == int_js_from_bytes(buf[10:12])
|
||||
if h2 != True:
|
||||
return False
|
||||
|
||||
# Everything up to this point is verified correct
|
||||
buf = self.xor_bytes(buf, 4, seed)
|
||||
v = self.generate_seed_hash(self.security_id, n2h_long(int_js_from_bytes(buf[4:8])))
|
||||
buf = self.xor_bytes(buf, 0, v)
|
||||
|
||||
h3 = self.calc_crc16(buf, 4) == int_js_from_bytes(buf[4:6])
|
||||
if h3 != True:
|
||||
return False
|
||||
|
||||
h4 = self.calc_crc16_alt(buf, 6) == int_js_from_bytes(buf[6:8])
|
||||
if h4 != True:
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
|
||||
def generate_password(self, year, month, day):
|
||||
# You can't input a code from before the game was released
|
||||
assert(year > 2000)
|
||||
assert(month > 8)
|
||||
|
||||
# Scramble the input password charset based on the game code + security cassette ID
|
||||
payload = day | shl(month, 8) | shl(year, 16)
|
||||
buf = int_js_to_bytes(payload, 4)
|
||||
|
||||
buf += int_js_to_bytes(self.calc_crc16(buf, 4), 2)
|
||||
buf += int_js_to_bytes(self.calc_crc16_alt(buf, 6), 2)
|
||||
|
||||
seed = self.generate_seed_hash(self.security_id, n2h_long(int_js_from_bytes(buf[4:8])))
|
||||
buf = self.xor_bytes(buf, 0, seed)
|
||||
|
||||
seed = self.generate_seed_hash("GN894EAA", self.security_id)
|
||||
buf = self.xor_bytes(buf, 4, seed)
|
||||
|
||||
buf += int_js_to_bytes(self.calc_crc16(buf, 8), 2)
|
||||
buf += int_js_to_bytes(self.calc_crc16_alt(buf, 10), 2)
|
||||
|
||||
# buf[:8] must equal the checksum at buf[8:10]
|
||||
h1 = self.calc_crc16(buf, 8) == int_js_from_bytes(buf[8:10])
|
||||
if h1 != True:
|
||||
return False
|
||||
|
||||
# buf[:10] must equal the checksum at buf[10:12]
|
||||
h2 = self.calc_crc16_alt(buf, 10) == int_js_from_bytes(buf[10:12])
|
||||
if h2 != True:
|
||||
return False
|
||||
|
||||
chunk1_payload = int_js_from_bytes(buf[:4])
|
||||
chunk2_payload = int_js_from_bytes(buf[4:8])
|
||||
chunk3_payload = int_js_from_bytes(buf[8:12])
|
||||
|
||||
seed = self.generate_seed_hash("GN894EAA", self.security_id)
|
||||
self.prng.init_rnd(seed)
|
||||
chunk3_payload ^= self.prng.irnd()
|
||||
|
||||
self.prng.init_rnd(int_js_from_bytes(buf[8:12]))
|
||||
chunk1_payload ^= self.prng.irnd()
|
||||
chunk2_payload ^= self.prng.irnd()
|
||||
|
||||
seed = self.generate_seed_hash(self.security_id, "GN894EAA")
|
||||
|
||||
chunk1 = self.encode_chunk(
|
||||
self.generate_scrambled_charset(seed),
|
||||
self.scramble_buffer_with_seed_even_more(
|
||||
seed + 0x381,
|
||||
chunk1_payload
|
||||
)
|
||||
)
|
||||
|
||||
chunk2 = self.encode_chunk(
|
||||
self.generate_scrambled_charset(seed + 0x240),
|
||||
self.scramble_buffer_with_seed_even_more(
|
||||
self.calc_crc16(chunk1),
|
||||
chunk2_payload
|
||||
)
|
||||
)
|
||||
|
||||
chunk3 = self.encode_chunk(
|
||||
self.generate_scrambled_charset(seed + 0x480),
|
||||
self.scramble_buffer_with_seed_even_more(
|
||||
self.calc_crc16_alt(chunk2),
|
||||
chunk3_payload
|
||||
)
|
||||
)
|
||||
|
||||
parts = []
|
||||
for x in [chunk1, chunk2, chunk3]:
|
||||
parts.append("".join([chr(c) for c in x]))
|
||||
|
||||
return "-".join(parts)
|
||||
|
||||
|
||||
def generate_password(machine_license_key, year=3030, day=9, month=22):
|
||||
irpass = EuromixIRPassword(machine_license_key)
|
||||
password = irpass.generate_password(year, day, month)
|
||||
|
||||
irpass_check = EuromixIRPassword(machine_license_key)
|
||||
if irpass_check.verify_password(password) == False:
|
||||
return "Failed to generate password!"
|
||||
|
||||
return password
|
Loading…
Reference in New Issue