mirror of
https://github.com/gchq/CyberChef.git
synced 2025-05-03 13:09:15 -04:00
adding prettier
This commit is contained in:
parent
c5a1b69c30
commit
ab0bc52d3c
717 changed files with 29324 additions and 18602 deletions
109
.eslintrc.json
109
.eslintrc.json
|
@ -28,13 +28,19 @@
|
|||
"radix": "warn",
|
||||
|
||||
// modify rules from base configurations
|
||||
"no-unused-vars": ["error", {
|
||||
"args": "none",
|
||||
"vars": "all"
|
||||
}],
|
||||
"no-empty": ["error", {
|
||||
"allowEmptyCatch": true
|
||||
}],
|
||||
"no-unused-vars": [
|
||||
"error",
|
||||
{
|
||||
"args": "none",
|
||||
"vars": "all"
|
||||
}
|
||||
],
|
||||
"no-empty": [
|
||||
"error",
|
||||
{
|
||||
"allowEmptyCatch": true
|
||||
}
|
||||
],
|
||||
|
||||
// disable rules from base configurations
|
||||
"no-control-regex": "off",
|
||||
|
@ -47,49 +53,72 @@
|
|||
"block-spacing": "error",
|
||||
"array-bracket-spacing": "error",
|
||||
"comma-spacing": "error",
|
||||
"spaced-comment": ["error", "always", { "exceptions": ["/"] } ],
|
||||
"spaced-comment": ["error", "always", { "exceptions": ["/"] }],
|
||||
"comma-style": "error",
|
||||
"computed-property-spacing": "error",
|
||||
"no-trailing-spaces": "warn",
|
||||
"eol-last": "error",
|
||||
"func-call-spacing": "error",
|
||||
"key-spacing": ["warn", {
|
||||
"mode": "minimum"
|
||||
}],
|
||||
"indent": ["error", 4, {
|
||||
"ignoreComments": true,
|
||||
"ArrayExpression": "first",
|
||||
"SwitchCase": 1
|
||||
}],
|
||||
"key-spacing": [
|
||||
"warn",
|
||||
{
|
||||
"mode": "minimum"
|
||||
}
|
||||
],
|
||||
"indent": [
|
||||
"error",
|
||||
4,
|
||||
{
|
||||
"ignoreComments": true,
|
||||
"ArrayExpression": "first",
|
||||
"SwitchCase": 1
|
||||
}
|
||||
],
|
||||
"linebreak-style": ["error", "unix"],
|
||||
"quotes": ["error", "double", {
|
||||
"avoidEscape": true,
|
||||
"allowTemplateLiterals": true
|
||||
}],
|
||||
"camelcase": ["error", {
|
||||
"properties": "always"
|
||||
}],
|
||||
"quotes": [
|
||||
"error",
|
||||
"double",
|
||||
{
|
||||
"avoidEscape": true,
|
||||
"allowTemplateLiterals": true
|
||||
}
|
||||
],
|
||||
"camelcase": [
|
||||
"error",
|
||||
{
|
||||
"properties": "always"
|
||||
}
|
||||
],
|
||||
"semi": ["error", "always"],
|
||||
"unicode-bom": "error",
|
||||
"require-jsdoc": ["error", {
|
||||
"require": {
|
||||
"FunctionDeclaration": true,
|
||||
"MethodDefinition": true,
|
||||
"ClassDeclaration": true,
|
||||
"ArrowFunctionExpression": true
|
||||
"require-jsdoc": [
|
||||
"error",
|
||||
{
|
||||
"require": {
|
||||
"FunctionDeclaration": true,
|
||||
"MethodDefinition": true,
|
||||
"ClassDeclaration": true,
|
||||
"ArrowFunctionExpression": true
|
||||
}
|
||||
}
|
||||
}],
|
||||
"keyword-spacing": ["error", {
|
||||
"before": true,
|
||||
"after": true
|
||||
}],
|
||||
"no-multiple-empty-lines": ["warn", {
|
||||
"max": 2,
|
||||
"maxEOF": 1,
|
||||
"maxBOF": 0
|
||||
}],
|
||||
],
|
||||
"keyword-spacing": [
|
||||
"error",
|
||||
{
|
||||
"before": true,
|
||||
"after": true
|
||||
}
|
||||
],
|
||||
"no-multiple-empty-lines": [
|
||||
"warn",
|
||||
{
|
||||
"max": 2,
|
||||
"maxEOF": 1,
|
||||
"maxBOF": 0
|
||||
}
|
||||
],
|
||||
"no-whitespace-before-property": "error",
|
||||
"operator-linebreak": ["error", "after"],
|
||||
"operator-linebreak": ["error", "before"],
|
||||
"space-in-parens": "error",
|
||||
"no-var": "error",
|
||||
"prefer-const": "error"
|
||||
|
|
2
.github/workflows/pull_requests.yml
vendored
2
.github/workflows/pull_requests.yml
vendored
|
@ -22,7 +22,7 @@ jobs:
|
|||
npm run setheapsize
|
||||
|
||||
- name: Lint
|
||||
run: npx grunt lint
|
||||
run: npm run style && npx grunt lint && git diff --exit-code
|
||||
|
||||
- name: Unit Tests
|
||||
run: |
|
||||
|
|
11
.prettierignore
Normal file
11
.prettierignore
Normal file
|
@ -0,0 +1,11 @@
|
|||
.github
|
||||
.devcontainer
|
||||
node_modules
|
||||
**/*.md
|
||||
.dockerignore
|
||||
.gitignore
|
||||
.editorconfig
|
||||
.gitattributes
|
||||
.npmignore
|
||||
package-lock.json
|
||||
package.json
|
11
.prettierrc
Normal file
11
.prettierrc
Normal file
|
@ -0,0 +1,11 @@
|
|||
{
|
||||
"tabWidth": 4,
|
||||
"useTabs": false,
|
||||
"printWidth": 120,
|
||||
"proseWrap": "always",
|
||||
"semi": true,
|
||||
"singleQuote": false,
|
||||
"bracketSpacing": true,
|
||||
"trailingComma": "none",
|
||||
"quoteProps": "preserve"
|
||||
}
|
198
Gruntfile.js
198
Gruntfile.js
|
@ -6,7 +6,8 @@ const BundleAnalyzerPlugin = require("webpack-bundle-analyzer").BundleAnalyzerPl
|
|||
const glob = require("glob");
|
||||
const path = require("path");
|
||||
|
||||
const nodeFlags = "--experimental-modules --experimental-json-modules --experimental-specifier-resolution=node --no-warnings --no-deprecation";
|
||||
const nodeFlags
|
||||
= "--experimental-modules --experimental-json-modules --experimental-specifier-resolution=node --no-warnings --no-deprecation";
|
||||
|
||||
/**
|
||||
* Grunt configuration for building the app in various formats.
|
||||
|
@ -21,56 +22,80 @@ module.exports = function (grunt) {
|
|||
grunt.file.preserveBOM = false;
|
||||
|
||||
// Tasks
|
||||
grunt.registerTask("dev",
|
||||
grunt.registerTask(
|
||||
"dev",
|
||||
"A persistent task which creates a development build whenever source files are modified.",
|
||||
["clean:dev", "clean:config", "exec:generateConfig", "concurrent:dev"]);
|
||||
["clean:dev", "clean:config", "exec:generateConfig", "concurrent:dev"]
|
||||
);
|
||||
|
||||
grunt.registerTask("prod",
|
||||
"Creates a production-ready build. Use the --msg flag to add a compile message.",
|
||||
[
|
||||
"eslint", "clean:prod", "clean:config", "exec:generateConfig", "findModules", "webpack:web",
|
||||
"copy:standalone", "zip:standalone", "clean:standalone", "exec:calcDownloadHash", "chmod"
|
||||
]);
|
||||
grunt.registerTask("prod", "Creates a production-ready build. Use the --msg flag to add a compile message.", [
|
||||
"eslint",
|
||||
"clean:prod",
|
||||
"clean:config",
|
||||
"exec:generateConfig",
|
||||
"findModules",
|
||||
"webpack:web",
|
||||
"copy:standalone",
|
||||
"zip:standalone",
|
||||
"clean:standalone",
|
||||
"exec:calcDownloadHash",
|
||||
"chmod"
|
||||
]);
|
||||
|
||||
grunt.registerTask("node",
|
||||
"Compiles CyberChef into a single NodeJS module.",
|
||||
[
|
||||
"clean:node", "clean:config", "clean:nodeConfig", "exec:generateConfig", "exec:generateNodeIndex"
|
||||
]);
|
||||
grunt.registerTask("node", "Compiles CyberChef into a single NodeJS module.", [
|
||||
"clean:node",
|
||||
"clean:config",
|
||||
"clean:nodeConfig",
|
||||
"exec:generateConfig",
|
||||
"exec:generateNodeIndex"
|
||||
]);
|
||||
|
||||
grunt.registerTask("configTests",
|
||||
grunt.registerTask(
|
||||
"configTests",
|
||||
"A task which configures config files in preparation for tests to be run. Use `npm test` to run tests.",
|
||||
[
|
||||
"clean:config", "clean:nodeConfig", "exec:generateConfig", "exec:generateNodeIndex"
|
||||
]);
|
||||
["clean:config", "clean:nodeConfig", "exec:generateConfig", "exec:generateNodeIndex"]
|
||||
);
|
||||
|
||||
grunt.registerTask("testui",
|
||||
grunt.registerTask(
|
||||
"testui",
|
||||
"A task which runs all the UI tests in the tests directory. The prod task must already have been run.",
|
||||
["connect:prod", "exec:browserTests"]);
|
||||
["connect:prod", "exec:browserTests"]
|
||||
);
|
||||
|
||||
grunt.registerTask("testnodeconsumer",
|
||||
grunt.registerTask(
|
||||
"testnodeconsumer",
|
||||
"A task which checks whether consuming CJS and ESM apps work with the CyberChef build",
|
||||
["exec:setupNodeConsumers", "exec:testCJSNodeConsumer", "exec:testESMNodeConsumer", "exec:teardownNodeConsumers"]);
|
||||
[
|
||||
"exec:setupNodeConsumers",
|
||||
"exec:testCJSNodeConsumer",
|
||||
"exec:testESMNodeConsumer",
|
||||
"exec:teardownNodeConsumers"
|
||||
]
|
||||
);
|
||||
|
||||
grunt.registerTask("default",
|
||||
"Lints the code base",
|
||||
["eslint", "exec:repoSize"]);
|
||||
grunt.registerTask("default", "Lints the code base", ["eslint", "exec:repoSize"]);
|
||||
|
||||
grunt.registerTask("lint", "eslint");
|
||||
|
||||
grunt.registerTask("findModules",
|
||||
grunt.registerTask(
|
||||
"findModules",
|
||||
"Finds all generated modules and updates the entry point list for Webpack",
|
||||
function(arg1, arg2) {
|
||||
function (arg1, arg2) {
|
||||
const moduleEntryPoints = listEntryModules();
|
||||
|
||||
grunt.log.writeln(`Found ${Object.keys(moduleEntryPoints).length} modules.`);
|
||||
|
||||
grunt.config.set("webpack.web.entry",
|
||||
Object.assign({
|
||||
main: "./src/web/index.js"
|
||||
}, moduleEntryPoints));
|
||||
});
|
||||
|
||||
grunt.config.set(
|
||||
"webpack.web.entry",
|
||||
Object.assign(
|
||||
{
|
||||
main: "./src/web/index.js"
|
||||
},
|
||||
moduleEntryPoints
|
||||
)
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
// Load tasks provided by each plugin
|
||||
grunt.loadNpmTasks("grunt-eslint");
|
||||
|
@ -84,7 +109,6 @@ module.exports = function (grunt) {
|
|||
grunt.loadNpmTasks("grunt-contrib-connect");
|
||||
grunt.loadNpmTasks("grunt-zip");
|
||||
|
||||
|
||||
// Project configuration
|
||||
const compileTime = grunt.template.today("UTC:dd/mm/yyyy HH:MM:ss") + " UTC",
|
||||
pkg = grunt.file.readJSON("package.json"),
|
||||
|
@ -92,7 +116,7 @@ module.exports = function (grunt) {
|
|||
BUILD_CONSTANTS = {
|
||||
COMPILE_TIME: JSON.stringify(compileTime),
|
||||
COMPILE_MSG: JSON.stringify(grunt.option("compile-msg") || grunt.option("msg") || ""),
|
||||
PKG_VERSION: JSON.stringify(pkg.version),
|
||||
PKG_VERSION: JSON.stringify(pkg.version)
|
||||
},
|
||||
moduleEntryPoints = listEntryModules(),
|
||||
nodeConsumerTestPath = "~/tmp-cyberchef",
|
||||
|
@ -104,13 +128,16 @@ module.exports = function (grunt) {
|
|||
return {
|
||||
mode: "production",
|
||||
target: "web",
|
||||
entry: Object.assign({
|
||||
main: "./src/web/index.js"
|
||||
}, moduleEntryPoints),
|
||||
entry: Object.assign(
|
||||
{
|
||||
main: "./src/web/index.js"
|
||||
},
|
||||
moduleEntryPoints
|
||||
),
|
||||
output: {
|
||||
path: __dirname + "/build/prod",
|
||||
filename: chunkData => {
|
||||
return chunkData.chunk.name === "main" ? "assets/[name].js": "[name].js";
|
||||
filename: (chunkData) => {
|
||||
return chunkData.chunk.name === "main" ? "assets/[name].js" : "[name].js";
|
||||
},
|
||||
globalObject: "this"
|
||||
},
|
||||
|
@ -138,19 +165,18 @@ module.exports = function (grunt) {
|
|||
analyzerMode: "static",
|
||||
reportFilename: "BundleAnalyzerReport.html",
|
||||
openAnalyzer: false
|
||||
}),
|
||||
})
|
||||
]
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Generates an entry list for all the modules.
|
||||
*/
|
||||
function listEntryModules() {
|
||||
const entryModules = {};
|
||||
|
||||
glob.sync("./src/core/config/modules/*.mjs").forEach(file => {
|
||||
glob.sync("./src/core/config/modules/*.mjs").forEach((file) => {
|
||||
const basename = path.basename(file);
|
||||
if (basename !== "Default.mjs" && basename !== "OpModules.mjs")
|
||||
entryModules["modules/" + basename.split(".mjs")[0]] = path.resolve(file);
|
||||
|
@ -171,12 +197,14 @@ module.exports = function (grunt) {
|
|||
if (!win) {
|
||||
return cmds.join(";");
|
||||
}
|
||||
return cmds
|
||||
// && means that subsequent commands will not be executed if the
|
||||
// previous one fails. & would coninue on a fail
|
||||
.join("&&")
|
||||
// Windows does not support \n properly
|
||||
.replace(/\n/g, "\\n");
|
||||
return (
|
||||
cmds
|
||||
// && means that subsequent commands will not be executed if the
|
||||
// previous one fails. & would coninue on a fail
|
||||
.join("&&")
|
||||
// Windows does not support \n properly
|
||||
.replace(/\n/g, "\\n")
|
||||
);
|
||||
}
|
||||
|
||||
grunt.initConfig({
|
||||
|
@ -184,7 +212,11 @@ module.exports = function (grunt) {
|
|||
dev: ["build/dev/*"],
|
||||
prod: ["build/prod/*"],
|
||||
node: ["build/node/*"],
|
||||
config: ["src/core/config/OperationConfig.json", "src/core/config/modules/*", "src/code/operations/index.mjs"],
|
||||
config: [
|
||||
"src/core/config/OperationConfig.json",
|
||||
"src/core/config/modules/*",
|
||||
"src/code/operations/index.mjs"
|
||||
],
|
||||
nodeConfig: ["src/node/index.mjs", "src/node/config/OperationConfig.json"],
|
||||
standalone: ["build/prod/CyberChef*.html"]
|
||||
},
|
||||
|
@ -194,20 +226,26 @@ module.exports = function (grunt) {
|
|||
web: ["src/web/**/*.{js,mjs}", "!src/web/static/**/*"],
|
||||
node: ["src/node/**/*.{js,mjs}"],
|
||||
tests: ["tests/**/*.{js,mjs}"],
|
||||
options: {
|
||||
fix: true
|
||||
}
|
||||
},
|
||||
webpack: {
|
||||
options: webpackConfig,
|
||||
myConfig: webpackConfig,
|
||||
web: webpackProdConf(),
|
||||
web: webpackProdConf()
|
||||
},
|
||||
"webpack-dev-server": {
|
||||
options: webpackConfig,
|
||||
start: {
|
||||
mode: "development",
|
||||
target: "web",
|
||||
entry: Object.assign({
|
||||
main: "./src/web/index.js"
|
||||
}, moduleEntryPoints),
|
||||
entry: Object.assign(
|
||||
{
|
||||
main: "./src/web/index.js"
|
||||
},
|
||||
moduleEntryPoints
|
||||
),
|
||||
resolve: {
|
||||
alias: {
|
||||
"./config/modules/OpModules.mjs": "./config/modules/Default.mjs"
|
||||
|
@ -228,7 +266,7 @@ module.exports = function (grunt) {
|
|||
template: "./src/web/html/index.html",
|
||||
chunks: ["main"],
|
||||
compileTime: compileTime,
|
||||
version: pkg.version,
|
||||
version: pkg.version
|
||||
})
|
||||
]
|
||||
}
|
||||
|
@ -236,11 +274,7 @@ module.exports = function (grunt) {
|
|||
zip: {
|
||||
standalone: {
|
||||
cwd: "build/prod/",
|
||||
src: [
|
||||
"build/prod/**/*",
|
||||
"!build/prod/index.html",
|
||||
"!build/prod/BundleAnalyzerReport.html",
|
||||
],
|
||||
src: ["build/prod/**/*", "!build/prod/index.html", "!build/prod/BundleAnalyzerReport.html"],
|
||||
dest: `build/prod/CyberChef_v${pkg.version}.zip`
|
||||
}
|
||||
},
|
||||
|
@ -258,14 +292,18 @@ module.exports = function (grunt) {
|
|||
process: function (content, srcpath) {
|
||||
if (srcpath.indexOf("index.html") >= 0) {
|
||||
// Add Google Analytics code to index.html
|
||||
content = content.replace("</body></html>",
|
||||
grunt.file.read("src/web/static/ga.html") + "</body></html>");
|
||||
content = content.replace(
|
||||
"</body></html>",
|
||||
grunt.file.read("src/web/static/ga.html") + "</body></html>"
|
||||
);
|
||||
|
||||
// Add Structured Data for SEO
|
||||
content = content.replace("</head>",
|
||||
"<script type='application/ld+json'>" +
|
||||
JSON.stringify(JSON.parse(grunt.file.read("src/web/static/structuredData.json"))) +
|
||||
"</script></head>");
|
||||
content = content.replace(
|
||||
"</head>",
|
||||
"<script type='application/ld+json'>"
|
||||
+ JSON.stringify(JSON.parse(grunt.file.read("src/web/static/structuredData.json")))
|
||||
+ "</script></head>"
|
||||
);
|
||||
return grunt.template.process(content, srcpath);
|
||||
} else {
|
||||
return content;
|
||||
|
@ -285,8 +323,10 @@ module.exports = function (grunt) {
|
|||
process: function (content, srcpath) {
|
||||
if (srcpath.indexOf("index.html") >= 0) {
|
||||
// Replace download link with version number
|
||||
content = content.replace(/<a [^>]+>Download CyberChef.+?<\/a>/,
|
||||
`<span>Version ${pkg.version}</span>`);
|
||||
content = content.replace(
|
||||
/<a [^>]+>Download CyberChef.+?<\/a>/,
|
||||
`<span>Version ${pkg.version}</span>`
|
||||
);
|
||||
|
||||
return grunt.template.process(content, srcpath);
|
||||
} else {
|
||||
|
@ -306,7 +346,7 @@ module.exports = function (grunt) {
|
|||
chmod: {
|
||||
build: {
|
||||
options: {
|
||||
mode: "755",
|
||||
mode: "755"
|
||||
},
|
||||
src: ["build/**/*", "build/"]
|
||||
}
|
||||
|
@ -338,7 +378,7 @@ module.exports = function (grunt) {
|
|||
`sed -i -e "s/DOWNLOAD_HASH_PLACEHOLDER/$(cat build/prod/sha256digest.txt)/" build/prod/index.html`
|
||||
]);
|
||||
}
|
||||
},
|
||||
}
|
||||
},
|
||||
repoSize: {
|
||||
command: chainCommands([
|
||||
|
@ -390,21 +430,15 @@ module.exports = function (grunt) {
|
|||
command: chainCommands([
|
||||
`rm -rf ${nodeConsumerTestPath}`,
|
||||
"echo '\n--- Node consumer tests complete ---'"
|
||||
]),
|
||||
])
|
||||
},
|
||||
testCJSNodeConsumer: {
|
||||
command: chainCommands([
|
||||
`cd ${nodeConsumerTestPath}`,
|
||||
`node ${nodeFlags} cjs-consumer.js`,
|
||||
]),
|
||||
stdout: false,
|
||||
command: chainCommands([`cd ${nodeConsumerTestPath}`, `node ${nodeFlags} cjs-consumer.js`]),
|
||||
stdout: false
|
||||
},
|
||||
testESMNodeConsumer: {
|
||||
command: chainCommands([
|
||||
`cd ${nodeConsumerTestPath}`,
|
||||
`node ${nodeFlags} esm-consumer.mjs`,
|
||||
]),
|
||||
stdout: false,
|
||||
command: chainCommands([`cd ${nodeConsumerTestPath}`, `node ${nodeFlags} esm-consumer.mjs`]),
|
||||
stdout: false
|
||||
},
|
||||
fixCryptoApiImports: {
|
||||
command: function () {
|
||||
|
@ -428,6 +462,6 @@ module.exports = function (grunt) {
|
|||
},
|
||||
stdout: false
|
||||
}
|
||||
},
|
||||
}
|
||||
});
|
||||
};
|
||||
|
|
|
@ -1,24 +1,29 @@
|
|||
module.exports = function(api) {
|
||||
module.exports = function (api) {
|
||||
api.cache.forever();
|
||||
|
||||
return {
|
||||
"presets": [
|
||||
["@babel/preset-env", {
|
||||
"modules": false,
|
||||
"useBuiltIns": "entry",
|
||||
"corejs": 3
|
||||
}]
|
||||
[
|
||||
"@babel/preset-env",
|
||||
{
|
||||
"modules": false,
|
||||
"useBuiltIns": "entry",
|
||||
"corejs": 3
|
||||
}
|
||||
]
|
||||
],
|
||||
"plugins": [
|
||||
"dynamic-import-node",
|
||||
"@babel/plugin-syntax-import-assertions",
|
||||
[
|
||||
"babel-plugin-transform-builtin-extend", {
|
||||
"babel-plugin-transform-builtin-extend",
|
||||
{
|
||||
"globals": ["Error"]
|
||||
}
|
||||
],
|
||||
[
|
||||
"@babel/plugin-transform-runtime", {
|
||||
"@babel/plugin-transform-runtime",
|
||||
{
|
||||
"regenerator": true
|
||||
}
|
||||
]
|
||||
|
|
|
@ -1,32 +1,29 @@
|
|||
{
|
||||
"src_folders": ["tests/browser"],
|
||||
"exclude": ["tests/browser/browserUtils.js"],
|
||||
"output_folder": "tests/browser/output",
|
||||
"src_folders": ["tests/browser"],
|
||||
"exclude": ["tests/browser/browserUtils.js"],
|
||||
"output_folder": "tests/browser/output",
|
||||
|
||||
"test_settings": {
|
||||
"test_settings": {
|
||||
"default": {
|
||||
"launch_url": "http://localhost:8080",
|
||||
"webdriver": {
|
||||
"start_process": true,
|
||||
"server_path": "./node_modules/.bin/chromedriver",
|
||||
"port": 9515,
|
||||
"log_path": "tests/browser/output"
|
||||
},
|
||||
"desiredCapabilities": {
|
||||
"browserName": "chrome"
|
||||
},
|
||||
"enable_fail_fast": true
|
||||
},
|
||||
|
||||
"default": {
|
||||
"launch_url": "http://localhost:8080",
|
||||
"webdriver": {
|
||||
"start_process": true,
|
||||
"server_path": "./node_modules/.bin/chromedriver",
|
||||
"port": 9515,
|
||||
"log_path": "tests/browser/output"
|
||||
},
|
||||
"desiredCapabilities": {
|
||||
"browserName": "chrome"
|
||||
},
|
||||
"enable_fail_fast": true
|
||||
},
|
||||
"dev": {
|
||||
"launch_url": "http://localhost:8080"
|
||||
},
|
||||
|
||||
"dev": {
|
||||
"launch_url": "http://localhost:8080"
|
||||
},
|
||||
|
||||
"prod": {
|
||||
"launch_url": "http://localhost:8000/index.html"
|
||||
"prod": {
|
||||
"launch_url": "http://localhost:8000/index.html"
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
16
package-lock.json
generated
16
package-lock.json
generated
|
@ -141,6 +141,7 @@
|
|||
"postcss-css-variables": "^0.19.0",
|
||||
"postcss-import": "^16.0.0",
|
||||
"postcss-loader": "^8.1.0",
|
||||
"prettier": "^3.2.5",
|
||||
"prompt": "^1.3.0",
|
||||
"sitemap": "^7.1.1",
|
||||
"terser": "^5.27.0",
|
||||
|
@ -12174,6 +12175,21 @@
|
|||
"node": ">= 0.8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/prettier": {
|
||||
"version": "3.2.5",
|
||||
"resolved": "https://registry.npmjs.org/prettier/-/prettier-3.2.5.tgz",
|
||||
"integrity": "sha512-3/GWa9aOC0YeD7LUfvOG2NiDyhOWRvt1k+rcKhOuYnMY24iiCphgneUfJDyFXd6rZCAnuLBv6UeAULtrhT/F4A==",
|
||||
"dev": true,
|
||||
"bin": {
|
||||
"prettier": "bin/prettier.cjs"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/prettier/prettier?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/pretty-error": {
|
||||
"version": "4.0.0",
|
||||
"dev": true,
|
||||
|
|
|
@ -82,6 +82,7 @@
|
|||
"postcss-css-variables": "^0.19.0",
|
||||
"postcss-import": "^16.0.0",
|
||||
"postcss-loader": "^8.1.0",
|
||||
"prettier": "^3.2.5",
|
||||
"prompt": "^1.3.0",
|
||||
"sitemap": "^7.1.1",
|
||||
"terser": "^5.27.0",
|
||||
|
@ -189,6 +190,8 @@
|
|||
"testui": "npx grunt testui",
|
||||
"testuidev": "npx nightwatch --env=dev",
|
||||
"lint": "npx grunt lint",
|
||||
"style": "prettier --write .",
|
||||
"check-style": "prettier --check .",
|
||||
"postinstall": "npx grunt exec:fixCryptoApiImports && npx grunt exec:fixSnackbarMarkup",
|
||||
"newop": "node --experimental-modules --experimental-json-modules src/core/config/scripts/newOperation.mjs",
|
||||
"minor": "node --experimental-modules --experimental-json-modules src/core/config/scripts/newMinorVersion.mjs",
|
||||
|
|
|
@ -4,6 +4,6 @@ module.exports = {
|
|||
require("autoprefixer"),
|
||||
require("postcss-css-variables")({
|
||||
preserve: true
|
||||
}),
|
||||
})
|
||||
]
|
||||
};
|
||||
|
|
|
@ -13,7 +13,6 @@ import { isWorkerEnvironment } from "./Utils.mjs";
|
|||
* The main controller for CyberChef.
|
||||
*/
|
||||
class Chef {
|
||||
|
||||
/**
|
||||
* Chef constructor
|
||||
*/
|
||||
|
@ -21,7 +20,6 @@ class Chef {
|
|||
this.dish = new Dish();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Runs the recipe over the input.
|
||||
*
|
||||
|
@ -36,12 +34,12 @@ class Chef {
|
|||
* @returns {number} response.progress - The position that we have got to in the recipe
|
||||
* @returns {number} response.duration - The number of ms it took to execute the recipe
|
||||
* @returns {number} response.error - The error object thrown by a failed operation (false if no error)
|
||||
*/
|
||||
async bake(input, recipeConfig, options={}) {
|
||||
*/
|
||||
async bake(input, recipeConfig, options = {}) {
|
||||
log.debug("Chef baking");
|
||||
const startTime = Date.now(),
|
||||
recipe = new Recipe(recipeConfig),
|
||||
containsFc = recipe.containsFlowControl();
|
||||
recipe = new Recipe(recipeConfig),
|
||||
containsFc = recipe.containsFlowControl();
|
||||
let error = false,
|
||||
progress = 0;
|
||||
|
||||
|
@ -56,7 +54,7 @@ class Chef {
|
|||
} catch (err) {
|
||||
log.error(err);
|
||||
error = {
|
||||
displayStr: err.displayStr,
|
||||
displayStr: err.displayStr
|
||||
};
|
||||
progress = err.progress;
|
||||
}
|
||||
|
@ -67,9 +65,8 @@ class Chef {
|
|||
// Present the raw result
|
||||
await recipe.present(this.dish);
|
||||
|
||||
const returnType =
|
||||
this.dish.type === Dish.HTML ? Dish.HTML :
|
||||
options?.returnType ? options.returnType : Dish.ARRAY_BUFFER;
|
||||
const returnType
|
||||
= this.dish.type === Dish.HTML ? Dish.HTML : options?.returnType ? options.returnType : Dish.ARRAY_BUFFER;
|
||||
|
||||
return {
|
||||
dish: rawDish,
|
||||
|
@ -81,7 +78,6 @@ class Chef {
|
|||
};
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* When a browser tab is unfocused and the browser has to run lots of dynamic content in other tabs,
|
||||
* it swaps out the memory for that tab. If the CyberChef tab has been unfocused for more than a
|
||||
|
@ -98,7 +94,7 @@ class Chef {
|
|||
*
|
||||
* @param {Object[]} recipeConfig - The recipe configuration object
|
||||
* @returns {number} The time it took to run the silent bake in milliseconds.
|
||||
*/
|
||||
*/
|
||||
silentBake(recipeConfig) {
|
||||
log.debug("Running silent bake");
|
||||
|
||||
|
@ -114,7 +110,6 @@ class Chef {
|
|||
return Date.now() - startTime;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Calculates highlight offsets if possible.
|
||||
*
|
||||
|
@ -153,7 +148,6 @@ class Chef {
|
|||
};
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Translates the dish to a specified type and returns it.
|
||||
*
|
||||
|
@ -173,11 +167,10 @@ class Chef {
|
|||
* @param {number} [maxLength=100]
|
||||
* @returns {string}
|
||||
*/
|
||||
async getDishTitle(dish, maxLength=100) {
|
||||
async getDishTitle(dish, maxLength = 100) {
|
||||
const newDish = new Dish(dish);
|
||||
return await newDish.getTitle(maxLength);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default Chef;
|
||||
|
|
|
@ -7,11 +7,10 @@
|
|||
*/
|
||||
|
||||
import Chef from "./Chef.mjs";
|
||||
import OperationConfig from "./config/OperationConfig.json" assert {type: "json"};
|
||||
import OperationConfig from "./config/OperationConfig.json" assert { type: "json" };
|
||||
import OpModules from "./config/modules/OpModules.mjs";
|
||||
import loglevelMessagePrefix from "loglevel-message-prefix";
|
||||
|
||||
|
||||
// Set up Chef instance
|
||||
self.chef = new Chef();
|
||||
|
||||
|
@ -19,7 +18,6 @@ self.OpModules = OpModules;
|
|||
self.OperationConfig = OperationConfig;
|
||||
self.inputNum = -1;
|
||||
|
||||
|
||||
// Tell the app that the worker has loaded and is ready to operate
|
||||
self.postMessage({
|
||||
action: "workerLoaded",
|
||||
|
@ -45,7 +43,7 @@ self.postMessage({
|
|||
* }
|
||||
* }
|
||||
*/
|
||||
self.addEventListener("message", function(e) {
|
||||
self.addEventListener("message", function (e) {
|
||||
// Handle message
|
||||
const r = e.data;
|
||||
log.debug(`Receiving command '${r.action}'`);
|
||||
|
@ -69,11 +67,7 @@ self.addEventListener("message", function(e) {
|
|||
self.docURL = r.data;
|
||||
break;
|
||||
case "highlight":
|
||||
calculateHighlights(
|
||||
r.data.recipeConfig,
|
||||
r.data.direction,
|
||||
r.data.pos
|
||||
);
|
||||
calculateHighlights(r.data.recipeConfig, r.data.direction, r.data.pos);
|
||||
break;
|
||||
case "setLogLevel":
|
||||
log.setLevel(r.data, false);
|
||||
|
@ -89,7 +83,6 @@ self.addEventListener("message", function(e) {
|
|||
}
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
* Baking handler
|
||||
*
|
||||
|
@ -101,24 +94,24 @@ async function bake(data) {
|
|||
try {
|
||||
self.inputNum = data.inputNum === undefined ? -1 : data.inputNum;
|
||||
const response = await self.chef.bake(
|
||||
data.input, // The user's input
|
||||
data.recipeConfig, // The configuration of the recipe
|
||||
data.options // Options set by the user
|
||||
data.input, // The user's input
|
||||
data.recipeConfig, // The configuration of the recipe
|
||||
data.options // Options set by the user
|
||||
);
|
||||
|
||||
const transferable = (response.dish.value instanceof ArrayBuffer) ?
|
||||
[response.dish.value] :
|
||||
undefined;
|
||||
|
||||
self.postMessage({
|
||||
action: "bakeComplete",
|
||||
data: Object.assign(response, {
|
||||
id: data.id,
|
||||
inputNum: data.inputNum,
|
||||
bakeId: data.bakeId
|
||||
})
|
||||
}, transferable);
|
||||
const transferable = response.dish.value instanceof ArrayBuffer ? [response.dish.value] : undefined;
|
||||
|
||||
self.postMessage(
|
||||
{
|
||||
action: "bakeComplete",
|
||||
data: Object.assign(response, {
|
||||
id: data.id,
|
||||
inputNum: data.inputNum,
|
||||
bakeId: data.bakeId
|
||||
})
|
||||
},
|
||||
transferable
|
||||
);
|
||||
} catch (err) {
|
||||
self.postMessage({
|
||||
action: "bakeError",
|
||||
|
@ -132,7 +125,6 @@ async function bake(data) {
|
|||
self.inputNum = -1;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Silent baking handler
|
||||
*/
|
||||
|
@ -145,23 +137,24 @@ function silentBake(data) {
|
|||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Translates the dish to a given type.
|
||||
*/
|
||||
async function getDishAs(data) {
|
||||
const value = await self.chef.getDishAs(data.dish, data.type);
|
||||
const transferable = (data.type === "ArrayBuffer") ? [value] : undefined;
|
||||
self.postMessage({
|
||||
action: "dishReturned",
|
||||
data: {
|
||||
value: value,
|
||||
id: data.id
|
||||
}
|
||||
}, transferable);
|
||||
const transferable = data.type === "ArrayBuffer" ? [value] : undefined;
|
||||
self.postMessage(
|
||||
{
|
||||
action: "dishReturned",
|
||||
data: {
|
||||
value: value,
|
||||
id: data.id
|
||||
}
|
||||
},
|
||||
transferable
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets the dish title
|
||||
*
|
||||
|
@ -181,7 +174,6 @@ async function getDishTitle(data) {
|
|||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Calculates highlight offsets if possible.
|
||||
*
|
||||
|
@ -200,14 +192,13 @@ async function calculateHighlights(recipeConfig, direction, pos) {
|
|||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Checks that all required modules are loaded and loads them if not.
|
||||
*
|
||||
* @param {Object} recipeConfig
|
||||
*/
|
||||
self.loadRequiredModules = function(recipeConfig) {
|
||||
recipeConfig.forEach(op => {
|
||||
self.loadRequiredModules = function (recipeConfig) {
|
||||
recipeConfig.forEach((op) => {
|
||||
const module = self.OperationConfig[op.op].module;
|
||||
|
||||
if (!(module in OpModules)) {
|
||||
|
@ -219,13 +210,12 @@ self.loadRequiredModules = function(recipeConfig) {
|
|||
});
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Send status update to the app.
|
||||
*
|
||||
* @param {string} msg
|
||||
*/
|
||||
self.sendStatusMessage = function(msg) {
|
||||
self.sendStatusMessage = function (msg) {
|
||||
self.postMessage({
|
||||
action: "statusMessage",
|
||||
data: {
|
||||
|
@ -235,14 +225,13 @@ self.sendStatusMessage = function(msg) {
|
|||
});
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Send progress update to the app.
|
||||
*
|
||||
* @param {number} progress
|
||||
* @param {number} total
|
||||
*/
|
||||
self.sendProgressMessage = function(progress, total) {
|
||||
self.sendProgressMessage = function (progress, total) {
|
||||
self.postMessage({
|
||||
action: "progressMessage",
|
||||
data: {
|
||||
|
@ -253,14 +242,13 @@ self.sendProgressMessage = function(progress, total) {
|
|||
});
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Send an option value update to the app.
|
||||
*
|
||||
* @param {string} option
|
||||
* @param {*} value
|
||||
*/
|
||||
self.setOption = function(option, value) {
|
||||
self.setOption = function (option, value) {
|
||||
self.postMessage({
|
||||
action: "optionUpdate",
|
||||
data: {
|
||||
|
@ -270,7 +258,6 @@ self.setOption = function(option, value) {
|
|||
});
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Send register values back to the app.
|
||||
*
|
||||
|
@ -278,7 +265,7 @@ self.setOption = function(option, value) {
|
|||
* @param {number} numPrevRegisters
|
||||
* @param {string[]} registers
|
||||
*/
|
||||
self.setRegisters = function(opIndex, numPrevRegisters, registers) {
|
||||
self.setRegisters = function (opIndex, numPrevRegisters, registers) {
|
||||
self.postMessage({
|
||||
action: "setRegisters",
|
||||
data: {
|
||||
|
|
|
@ -20,12 +20,10 @@ import DishListFile from "./dishTypes/DishListFile.mjs";
|
|||
import DishNumber from "./dishTypes/DishNumber.mjs";
|
||||
import DishString from "./dishTypes/DishString.mjs";
|
||||
|
||||
|
||||
/**
|
||||
* The data being operated on by each operation.
|
||||
*/
|
||||
class Dish {
|
||||
|
||||
/**
|
||||
* Dish constructor
|
||||
*
|
||||
|
@ -34,26 +32,27 @@ class Dish {
|
|||
* @param {Enum} [type=null] (optional) - A type to accompany object
|
||||
* literal input
|
||||
*/
|
||||
constructor(dishOrInput=null, type = null) {
|
||||
constructor(dishOrInput = null, type = null) {
|
||||
this.value = new ArrayBuffer(0);
|
||||
this.type = Dish.ARRAY_BUFFER;
|
||||
|
||||
// Case: dishOrInput is dish object
|
||||
if (dishOrInput &&
|
||||
Object.prototype.hasOwnProperty.call(dishOrInput, "value") &&
|
||||
Object.prototype.hasOwnProperty.call(dishOrInput, "type")) {
|
||||
if (
|
||||
dishOrInput
|
||||
&& Object.prototype.hasOwnProperty.call(dishOrInput, "value")
|
||||
&& Object.prototype.hasOwnProperty.call(dishOrInput, "type")
|
||||
) {
|
||||
this.set(dishOrInput.value, dishOrInput.type);
|
||||
// input and type defined separately
|
||||
// input and type defined separately
|
||||
} else if (dishOrInput && type !== null) {
|
||||
this.set(dishOrInput, type);
|
||||
// No type declared, so infer it.
|
||||
// No type declared, so infer it.
|
||||
} else if (dishOrInput) {
|
||||
const inferredType = Dish.typeEnum(dishOrInput.constructor.name);
|
||||
this.set(dishOrInput, inferredType);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the data type enum for the given type string.
|
||||
*
|
||||
|
@ -89,7 +88,6 @@ class Dish {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the data type string for the given type enum.
|
||||
*
|
||||
|
@ -121,7 +119,6 @@ class Dish {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the value of the data in the type format specified.
|
||||
*
|
||||
|
@ -136,13 +133,12 @@ class Dish {
|
|||
}
|
||||
|
||||
if (this.type !== type) {
|
||||
|
||||
// Node environment => _translate is sync
|
||||
if (isNodeEnvironment()) {
|
||||
this._translate(type);
|
||||
return this.value;
|
||||
|
||||
// Browser environment => _translate is async
|
||||
// Browser environment => _translate is async
|
||||
} else {
|
||||
return new Promise((resolve, reject) => {
|
||||
this._translate(type)
|
||||
|
@ -157,7 +153,6 @@ class Dish {
|
|||
return this.value;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the data value and type and then validates them.
|
||||
*
|
||||
|
@ -196,7 +191,6 @@ class Dish {
|
|||
return clone.get(type);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Detects the MIME type of the current dish
|
||||
* @returns {string}
|
||||
|
@ -212,7 +206,6 @@ class Dish {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the title of the data up to the specified length
|
||||
*
|
||||
|
@ -241,7 +234,7 @@ class Dish {
|
|||
case Dish.BYTE_ARRAY:
|
||||
title = this.detectDishType();
|
||||
if (title !== null) break;
|
||||
// fall through if no mime type was detected
|
||||
// fall through if no mime type was detected
|
||||
default:
|
||||
try {
|
||||
cloned = this.clone();
|
||||
|
@ -260,7 +253,7 @@ class Dish {
|
|||
* May have to disable parts of BYTE_ARRAY validation if it effects performance.
|
||||
*
|
||||
* @returns {boolean} Whether the data is valid or not.
|
||||
*/
|
||||
*/
|
||||
valid() {
|
||||
switch (this.type) {
|
||||
case Dish.BYTE_ARRAY:
|
||||
|
@ -270,9 +263,7 @@ class Dish {
|
|||
|
||||
// Check that every value is a number between 0 - 255
|
||||
for (let i = 0; i < this.value.length; i++) {
|
||||
if (typeof this.value[i] !== "number" ||
|
||||
this.value[i] < 0 ||
|
||||
this.value[i] > 255) {
|
||||
if (typeof this.value[i] !== "number" || this.value[i] < 0 || this.value[i] > 255) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -306,21 +297,21 @@ class Dish {
|
|||
case Dish.FILE:
|
||||
return this.value instanceof File;
|
||||
case Dish.LIST_FILE:
|
||||
return this.value instanceof Array &&
|
||||
this.value.reduce((acc, curr) => acc && curr instanceof File, true);
|
||||
return (
|
||||
this.value instanceof Array && this.value.reduce((acc, curr) => acc && curr instanceof File, true)
|
||||
);
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Determines how much space the Dish takes up.
|
||||
* Numbers in JavaScript are 64-bit floating point, however for the purposes of the Dish,
|
||||
* we measure how many bytes are taken up when the number is written as a string.
|
||||
*
|
||||
* @returns {number}
|
||||
*/
|
||||
*/
|
||||
get size() {
|
||||
switch (this.type) {
|
||||
case Dish.BYTE_ARRAY:
|
||||
|
@ -343,7 +334,6 @@ class Dish {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a deep clone of the current Dish.
|
||||
*
|
||||
|
@ -358,25 +348,16 @@ class Dish {
|
|||
case Dish.NUMBER:
|
||||
case Dish.BIG_NUMBER:
|
||||
// These data types are immutable so it is acceptable to copy them by reference
|
||||
newDish.set(
|
||||
this.value,
|
||||
this.type
|
||||
);
|
||||
newDish.set(this.value, this.type);
|
||||
break;
|
||||
case Dish.BYTE_ARRAY:
|
||||
case Dish.JSON:
|
||||
// These data types are mutable so they need to be copied by value
|
||||
newDish.set(
|
||||
JSON.parse(JSON.stringify(this.value)),
|
||||
this.type
|
||||
);
|
||||
newDish.set(JSON.parse(JSON.stringify(this.value)), this.type);
|
||||
break;
|
||||
case Dish.ARRAY_BUFFER:
|
||||
// Slicing an ArrayBuffer returns a new ArrayBuffer with a copy its contents
|
||||
newDish.set(
|
||||
this.value.slice(0),
|
||||
this.type
|
||||
);
|
||||
newDish.set(this.value.slice(0), this.type);
|
||||
break;
|
||||
case Dish.FILE:
|
||||
// A new file can be created by copying over all the values from the original
|
||||
|
@ -390,11 +371,12 @@ class Dish {
|
|||
break;
|
||||
case Dish.LIST_FILE:
|
||||
newDish.set(
|
||||
this.value.map(f =>
|
||||
new File([f], f.name, {
|
||||
"type": f.type,
|
||||
"lastModified": f.lastModified
|
||||
})
|
||||
this.value.map(
|
||||
(f) =>
|
||||
new File([f], f.name, {
|
||||
"type": f.type,
|
||||
"lastModified": f.lastModified
|
||||
})
|
||||
),
|
||||
this.type
|
||||
);
|
||||
|
@ -423,11 +405,11 @@ class Dish {
|
|||
this.type = Dish.ARRAY_BUFFER;
|
||||
this._fromArrayBuffer(toType);
|
||||
|
||||
// Browser environment => translate is async
|
||||
// Browser environment => translate is async
|
||||
} else {
|
||||
return new Promise((resolve, reject) => {
|
||||
this._toArrayBuffer()
|
||||
.then(() => this.type = Dish.ARRAY_BUFFER)
|
||||
.then(() => (this.type = Dish.ARRAY_BUFFER))
|
||||
.then(() => {
|
||||
this._fromArrayBuffer(toType);
|
||||
resolve();
|
||||
|
@ -435,7 +417,6 @@ class Dish {
|
|||
.catch(reject);
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -449,31 +430,31 @@ class Dish {
|
|||
// Using 'bind' here to allow this.value to be mutated within translation functions
|
||||
const toByteArrayFuncs = {
|
||||
browser: {
|
||||
[Dish.STRING]: () => Promise.resolve(DishString.toArrayBuffer.bind(this)()),
|
||||
[Dish.NUMBER]: () => Promise.resolve(DishNumber.toArrayBuffer.bind(this)()),
|
||||
[Dish.HTML]: () => Promise.resolve(DishHTML.toArrayBuffer.bind(this)()),
|
||||
[Dish.ARRAY_BUFFER]: () => Promise.resolve(),
|
||||
[Dish.BIG_NUMBER]: () => Promise.resolve(DishBigNumber.toArrayBuffer.bind(this)()),
|
||||
[Dish.JSON]: () => Promise.resolve(DishJSON.toArrayBuffer.bind(this)()),
|
||||
[Dish.FILE]: () => DishFile.toArrayBuffer.bind(this)(),
|
||||
[Dish.LIST_FILE]: () => Promise.resolve(DishListFile.toArrayBuffer.bind(this)()),
|
||||
[Dish.BYTE_ARRAY]: () => Promise.resolve(DishByteArray.toArrayBuffer.bind(this)()),
|
||||
[Dish.STRING]: () => Promise.resolve(DishString.toArrayBuffer.bind(this)()),
|
||||
[Dish.NUMBER]: () => Promise.resolve(DishNumber.toArrayBuffer.bind(this)()),
|
||||
[Dish.HTML]: () => Promise.resolve(DishHTML.toArrayBuffer.bind(this)()),
|
||||
[Dish.ARRAY_BUFFER]: () => Promise.resolve(),
|
||||
[Dish.BIG_NUMBER]: () => Promise.resolve(DishBigNumber.toArrayBuffer.bind(this)()),
|
||||
[Dish.JSON]: () => Promise.resolve(DishJSON.toArrayBuffer.bind(this)()),
|
||||
[Dish.FILE]: () => DishFile.toArrayBuffer.bind(this)(),
|
||||
[Dish.LIST_FILE]: () => Promise.resolve(DishListFile.toArrayBuffer.bind(this)()),
|
||||
[Dish.BYTE_ARRAY]: () => Promise.resolve(DishByteArray.toArrayBuffer.bind(this)())
|
||||
},
|
||||
node: {
|
||||
[Dish.STRING]: () => DishString.toArrayBuffer.bind(this)(),
|
||||
[Dish.NUMBER]: () => DishNumber.toArrayBuffer.bind(this)(),
|
||||
[Dish.HTML]: () => DishHTML.toArrayBuffer.bind(this)(),
|
||||
[Dish.ARRAY_BUFFER]: () => {},
|
||||
[Dish.BIG_NUMBER]: () => DishBigNumber.toArrayBuffer.bind(this)(),
|
||||
[Dish.JSON]: () => DishJSON.toArrayBuffer.bind(this)(),
|
||||
[Dish.FILE]: () => DishFile.toArrayBuffer.bind(this)(),
|
||||
[Dish.LIST_FILE]: () => DishListFile.toArrayBuffer.bind(this)(),
|
||||
[Dish.BYTE_ARRAY]: () => DishByteArray.toArrayBuffer.bind(this)(),
|
||||
[Dish.STRING]: () => DishString.toArrayBuffer.bind(this)(),
|
||||
[Dish.NUMBER]: () => DishNumber.toArrayBuffer.bind(this)(),
|
||||
[Dish.HTML]: () => DishHTML.toArrayBuffer.bind(this)(),
|
||||
[Dish.ARRAY_BUFFER]: () => {},
|
||||
[Dish.BIG_NUMBER]: () => DishBigNumber.toArrayBuffer.bind(this)(),
|
||||
[Dish.JSON]: () => DishJSON.toArrayBuffer.bind(this)(),
|
||||
[Dish.FILE]: () => DishFile.toArrayBuffer.bind(this)(),
|
||||
[Dish.LIST_FILE]: () => DishListFile.toArrayBuffer.bind(this)(),
|
||||
[Dish.BYTE_ARRAY]: () => DishByteArray.toArrayBuffer.bind(this)()
|
||||
}
|
||||
};
|
||||
|
||||
try {
|
||||
return toByteArrayFuncs[isNodeEnvironment() && "node" || "browser"][this.type]();
|
||||
return toByteArrayFuncs[(isNodeEnvironment() && "node") || "browser"][this.type]();
|
||||
} catch (err) {
|
||||
throw new DishError(`Error translating from ${Dish.enumLookup(this.type)} to ArrayBuffer: ${err}`);
|
||||
}
|
||||
|
@ -483,20 +464,19 @@ class Dish {
|
|||
* Convert this.value to the given type from ArrayBuffer
|
||||
*
|
||||
* @param {number} toType - the Dish enum to convert to
|
||||
*/
|
||||
*/
|
||||
_fromArrayBuffer(toType) {
|
||||
|
||||
// Using 'bind' here to allow this.value to be mutated within translation functions
|
||||
const toTypeFunctions = {
|
||||
[Dish.STRING]: () => DishString.fromArrayBuffer.bind(this)(),
|
||||
[Dish.NUMBER]: () => DishNumber.fromArrayBuffer.bind(this)(),
|
||||
[Dish.HTML]: () => DishHTML.fromArrayBuffer.bind(this)(),
|
||||
[Dish.ARRAY_BUFFER]: () => {},
|
||||
[Dish.BIG_NUMBER]: () => DishBigNumber.fromArrayBuffer.bind(this)(),
|
||||
[Dish.JSON]: () => DishJSON.fromArrayBuffer.bind(this)(),
|
||||
[Dish.FILE]: () => DishFile.fromArrayBuffer.bind(this)(),
|
||||
[Dish.LIST_FILE]: () => DishListFile.fromArrayBuffer.bind(this)(),
|
||||
[Dish.BYTE_ARRAY]: () => DishByteArray.fromArrayBuffer.bind(this)(),
|
||||
[Dish.STRING]: () => DishString.fromArrayBuffer.bind(this)(),
|
||||
[Dish.NUMBER]: () => DishNumber.fromArrayBuffer.bind(this)(),
|
||||
[Dish.HTML]: () => DishHTML.fromArrayBuffer.bind(this)(),
|
||||
[Dish.ARRAY_BUFFER]: () => {},
|
||||
[Dish.BIG_NUMBER]: () => DishBigNumber.fromArrayBuffer.bind(this)(),
|
||||
[Dish.JSON]: () => DishJSON.fromArrayBuffer.bind(this)(),
|
||||
[Dish.FILE]: () => DishFile.fromArrayBuffer.bind(this)(),
|
||||
[Dish.LIST_FILE]: () => DishListFile.fromArrayBuffer.bind(this)(),
|
||||
[Dish.BYTE_ARRAY]: () => DishByteArray.fromArrayBuffer.bind(this)()
|
||||
};
|
||||
|
||||
try {
|
||||
|
@ -506,10 +486,8 @@ class Dish {
|
|||
throw new DishError(`Error translating from ArrayBuffer to ${Dish.enumLookup(toType)}: ${err}`);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Dish data type enum for byte arrays.
|
||||
* @readonly
|
||||
|
@ -559,11 +537,10 @@ Dish.JSON = 6;
|
|||
*/
|
||||
Dish.FILE = 7;
|
||||
/**
|
||||
* Dish data type enum for lists of files.
|
||||
* @readonly
|
||||
* @enum
|
||||
*/
|
||||
* Dish data type enum for lists of files.
|
||||
* @readonly
|
||||
* @enum
|
||||
*/
|
||||
Dish.LIST_FILE = 8;
|
||||
|
||||
|
||||
export default Dish;
|
||||
|
|
|
@ -5,21 +5,20 @@
|
|||
*/
|
||||
|
||||
import Utils from "./Utils.mjs";
|
||||
import {fromHex} from "./lib/Hex.mjs";
|
||||
import { fromHex } from "./lib/Hex.mjs";
|
||||
|
||||
/**
|
||||
* The arguments to operations.
|
||||
*/
|
||||
class Ingredient {
|
||||
|
||||
/**
|
||||
* Ingredient constructor
|
||||
*
|
||||
* @param {Object} ingredientConfig
|
||||
*/
|
||||
constructor(ingredientConfig) {
|
||||
this.name = "";
|
||||
this.type = "";
|
||||
this.name = "";
|
||||
this.type = "";
|
||||
this._value = null;
|
||||
this.disabled = false;
|
||||
this.hint = "";
|
||||
|
@ -37,7 +36,6 @@ class Ingredient {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Reads and parses the given config.
|
||||
*
|
||||
|
@ -60,7 +58,6 @@ class Ingredient {
|
|||
this.step = ingredientConfig.step;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the value of the Ingredient as it should be displayed in a recipe config.
|
||||
*
|
||||
|
@ -70,7 +67,6 @@ class Ingredient {
|
|||
return this._value;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the value of the Ingredient.
|
||||
*
|
||||
|
@ -80,7 +76,6 @@ class Ingredient {
|
|||
this._value = Ingredient.prepare(value, this.type);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets the value of the Ingredient.
|
||||
*
|
||||
|
@ -90,14 +85,13 @@ class Ingredient {
|
|||
return this._value;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Most values will be strings when they are entered. This function converts them to the correct
|
||||
* type.
|
||||
*
|
||||
* @param {*} data
|
||||
* @param {string} type - The name of the data type.
|
||||
*/
|
||||
*/
|
||||
static prepare(data, type) {
|
||||
let number;
|
||||
|
||||
|
@ -126,7 +120,6 @@ class Ingredient {
|
|||
return data;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default Ingredient;
|
||||
|
|
|
@ -11,29 +11,27 @@ import Ingredient from "./Ingredient.mjs";
|
|||
* The Operation specified by the user to be run.
|
||||
*/
|
||||
class Operation {
|
||||
|
||||
/**
|
||||
* Operation constructor
|
||||
*/
|
||||
constructor() {
|
||||
// Private fields
|
||||
this._inputType = -1;
|
||||
this._outputType = -1;
|
||||
this._presentType = -1;
|
||||
this._breakpoint = false;
|
||||
this._disabled = false;
|
||||
this._flowControl = false;
|
||||
this._manualBake = false;
|
||||
this._ingList = [];
|
||||
this._inputType = -1;
|
||||
this._outputType = -1;
|
||||
this._presentType = -1;
|
||||
this._breakpoint = false;
|
||||
this._disabled = false;
|
||||
this._flowControl = false;
|
||||
this._manualBake = false;
|
||||
this._ingList = [];
|
||||
|
||||
// Public fields
|
||||
this.name = "";
|
||||
this.module = "";
|
||||
this.description = "";
|
||||
this.infoURL = null;
|
||||
this.name = "";
|
||||
this.module = "";
|
||||
this.description = "";
|
||||
this.infoURL = null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Interface for operation runner
|
||||
*
|
||||
|
@ -45,7 +43,6 @@ class Operation {
|
|||
return input;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Interface for forward highlighter
|
||||
*
|
||||
|
@ -59,7 +56,6 @@ class Operation {
|
|||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Interface for reverse highlighter
|
||||
*
|
||||
|
@ -73,7 +69,6 @@ class Operation {
|
|||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Method to be called when displaying the result of an operation in a human-readable
|
||||
* format. This allows operations to return usable data from their run() method and
|
||||
|
@ -90,7 +85,6 @@ class Operation {
|
|||
return data;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the input type as a Dish enum.
|
||||
*
|
||||
|
@ -100,7 +94,6 @@ class Operation {
|
|||
this._inputType = Dish.typeEnum(typeStr);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets the input type as a readable string.
|
||||
*
|
||||
|
@ -110,7 +103,6 @@ class Operation {
|
|||
return Dish.enumLookup(this._inputType);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the output type as a Dish enum.
|
||||
*
|
||||
|
@ -121,7 +113,6 @@ class Operation {
|
|||
if (this._presentType < 0) this._presentType = this._outputType;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets the output type as a readable string.
|
||||
*
|
||||
|
@ -131,7 +122,6 @@ class Operation {
|
|||
return Dish.enumLookup(this._outputType);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the presentation type as a Dish enum.
|
||||
*
|
||||
|
@ -141,7 +131,6 @@ class Operation {
|
|||
this._presentType = Dish.typeEnum(typeStr);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets the presentation type as a readable string.
|
||||
*
|
||||
|
@ -151,27 +140,25 @@ class Operation {
|
|||
return Dish.enumLookup(this._presentType);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the args for the current operation.
|
||||
*
|
||||
* @param {Object[]} conf
|
||||
*/
|
||||
set args(conf) {
|
||||
conf.forEach(arg => {
|
||||
conf.forEach((arg) => {
|
||||
const ingredient = new Ingredient(arg);
|
||||
this.addIngredient(ingredient);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets the args for the current operation.
|
||||
*
|
||||
* @param {Object[]} conf
|
||||
*/
|
||||
get args() {
|
||||
return this._ingList.map(ing => {
|
||||
return this._ingList.map((ing) => {
|
||||
const conf = {
|
||||
name: ing.name,
|
||||
type: ing.type,
|
||||
|
@ -192,7 +179,6 @@ class Operation {
|
|||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the value of the Operation as it should be displayed in a recipe config.
|
||||
*
|
||||
|
@ -201,11 +187,10 @@ class Operation {
|
|||
get config() {
|
||||
return {
|
||||
"op": this.name,
|
||||
"args": this._ingList.map(ing => ing.config)
|
||||
"args": this._ingList.map((ing) => ing.config)
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Adds a new Ingredient to this Operation.
|
||||
*
|
||||
|
@ -215,7 +200,6 @@ class Operation {
|
|||
this._ingList.push(ingredient);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set the Ingredient values for this Operation.
|
||||
*
|
||||
|
@ -227,17 +211,15 @@ class Operation {
|
|||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the Ingredient values for this Operation.
|
||||
*
|
||||
* @returns {Object[]}
|
||||
*/
|
||||
get ingValues() {
|
||||
return this._ingList.map(ing => ing.value);
|
||||
return this._ingList.map((ing) => ing.value);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set whether this Operation has a breakpoint.
|
||||
*
|
||||
|
@ -247,7 +229,6 @@ class Operation {
|
|||
this._breakpoint = !!value;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns true if this Operation has a breakpoint set.
|
||||
*
|
||||
|
@ -257,7 +238,6 @@ class Operation {
|
|||
return this._breakpoint;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set whether this Operation is disabled.
|
||||
*
|
||||
|
@ -267,7 +247,6 @@ class Operation {
|
|||
this._disabled = !!value;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns true if this Operation is disabled.
|
||||
*
|
||||
|
@ -277,7 +256,6 @@ class Operation {
|
|||
return this._disabled;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns true if this Operation is a flow control.
|
||||
*
|
||||
|
@ -287,7 +265,6 @@ class Operation {
|
|||
return this._flowControl;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set whether this Operation is a flowcontrol op.
|
||||
*
|
||||
|
@ -297,7 +274,6 @@ class Operation {
|
|||
this._flowControl = !!value;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns true if this Operation should not trigger AutoBake.
|
||||
*
|
||||
|
@ -307,7 +283,6 @@ class Operation {
|
|||
return this._manualBake;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set whether this Operation should trigger AutoBake.
|
||||
*
|
||||
|
@ -316,7 +291,6 @@ class Operation {
|
|||
set manualBake(value) {
|
||||
this._manualBake = !!value;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default Operation;
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
* @license Apache-2.0
|
||||
*/
|
||||
|
||||
import OperationConfig from "./config/OperationConfig.json" assert {type: "json"};
|
||||
import OperationConfig from "./config/OperationConfig.json" assert { type: "json" };
|
||||
import OperationError from "./errors/OperationError.mjs";
|
||||
import Operation from "./Operation.mjs";
|
||||
import DishError from "./errors/DishError.mjs";
|
||||
|
@ -17,8 +17,7 @@ let modules = null;
|
|||
/**
|
||||
* The Recipe controls a list of Operations and the Dish they operate on.
|
||||
*/
|
||||
class Recipe {
|
||||
|
||||
class Recipe {
|
||||
/**
|
||||
* Recipe constructor
|
||||
*
|
||||
|
@ -32,7 +31,6 @@ class Recipe {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Reads and parses the given config.
|
||||
*
|
||||
|
@ -40,18 +38,17 @@ class Recipe {
|
|||
* @param {Object} recipeConfig
|
||||
*/
|
||||
_parseConfig(recipeConfig) {
|
||||
recipeConfig.forEach(c => {
|
||||
recipeConfig.forEach((c) => {
|
||||
this.opList.push({
|
||||
name: c.op,
|
||||
module: OperationConfig[c.op].module,
|
||||
ingValues: c.args,
|
||||
breakpoint: c.breakpoint,
|
||||
disabled: c.disabled || c.op === "Comment",
|
||||
disabled: c.disabled || c.op === "Comment"
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Populate elements of opList with operation instances.
|
||||
* Dynamic import here removes top-level cyclic dependency issue.
|
||||
|
@ -66,7 +63,7 @@ class Recipe {
|
|||
modules = modules.default;
|
||||
}
|
||||
|
||||
this.opList = this.opList.map(o => {
|
||||
this.opList = this.opList.map((o) => {
|
||||
if (o instanceof Operation) {
|
||||
return o;
|
||||
} else {
|
||||
|
@ -79,20 +76,18 @@ class Recipe {
|
|||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the value of the Recipe as it should be displayed in a recipe config.
|
||||
*
|
||||
* @returns {Object[]}
|
||||
*/
|
||||
get config() {
|
||||
return this.opList.map(op => ({
|
||||
return this.opList.map((op) => ({
|
||||
op: op.name,
|
||||
args: op.ingValues,
|
||||
args: op.ingValues
|
||||
}));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Adds a new Operation to this Recipe.
|
||||
*
|
||||
|
@ -102,14 +97,13 @@ class Recipe {
|
|||
this.opList.push(operation);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Adds a list of Operations to this Recipe.
|
||||
*
|
||||
* @param {Operation[]} operations
|
||||
*/
|
||||
addOperations(operations) {
|
||||
operations.forEach(o => {
|
||||
operations.forEach((o) => {
|
||||
if (o instanceof Operation) {
|
||||
this.opList.push(o);
|
||||
} else {
|
||||
|
@ -118,13 +112,12 @@ class Recipe {
|
|||
module: o.module,
|
||||
ingValues: o.args,
|
||||
breakpoint: o.breakpoint,
|
||||
disabled: o.disabled,
|
||||
disabled: o.disabled
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set a breakpoint on a specified Operation.
|
||||
*
|
||||
|
@ -139,7 +132,6 @@ class Recipe {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Remove breakpoints on all Operations in the Recipe up to the specified position. Used by Flow
|
||||
* Control Fork operation.
|
||||
|
@ -152,7 +144,6 @@ class Recipe {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns true if there is a Flow Control Operation in this Recipe.
|
||||
*
|
||||
|
@ -164,7 +155,6 @@ class Recipe {
|
|||
}, false);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Executes each operation in the recipe over the given Dish.
|
||||
*
|
||||
|
@ -176,8 +166,10 @@ class Recipe {
|
|||
* @returns {number}
|
||||
* - The final progress through the recipe
|
||||
*/
|
||||
async execute(dish, startFrom=0, forkState={}) {
|
||||
let op, input, output,
|
||||
async execute(dish, startFrom = 0, forkState = {}) {
|
||||
let op,
|
||||
input,
|
||||
output,
|
||||
numJumps = 0,
|
||||
numRegisters = forkState.numRegisters || 0;
|
||||
|
||||
|
@ -204,19 +196,19 @@ class Recipe {
|
|||
log.debug(`Executing operation '${op.name}'`);
|
||||
|
||||
if (isWorkerEnvironment()) {
|
||||
self.sendStatusMessage(`Baking... (${i+1}/${this.opList.length})`);
|
||||
self.sendStatusMessage(`Baking... (${i + 1}/${this.opList.length})`);
|
||||
self.sendProgressMessage(i + 1, this.opList.length);
|
||||
}
|
||||
|
||||
if (op.flowControl) {
|
||||
// Package up the current state
|
||||
let state = {
|
||||
"progress": i,
|
||||
"dish": dish,
|
||||
"opList": this.opList,
|
||||
"numJumps": numJumps,
|
||||
"progress": i,
|
||||
"dish": dish,
|
||||
"opList": this.opList,
|
||||
"numJumps": numJumps,
|
||||
"numRegisters": numRegisters,
|
||||
"forkOffset": forkState.forkOffset || 0
|
||||
"forkOffset": forkState.forkOffset || 0
|
||||
};
|
||||
|
||||
state = await op.run(state);
|
||||
|
@ -243,8 +235,9 @@ class Recipe {
|
|||
|
||||
e.progress = i;
|
||||
if (e.fileName) {
|
||||
e.displayStr = `${op.name} - ${e.name} in ${e.fileName} on line ` +
|
||||
`${e.lineNumber}.<br><br>Message: ${e.displayStr || e.message}`;
|
||||
e.displayStr
|
||||
= `${op.name} - ${e.name} in ${e.fileName} on line `
|
||||
+ `${e.lineNumber}.<br><br>Message: ${e.displayStr || e.message}`;
|
||||
} else {
|
||||
e.displayStr = `${op.name} - ${e.displayStr || e.message}`;
|
||||
}
|
||||
|
@ -258,7 +251,6 @@ class Recipe {
|
|||
return this.opList.length;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Present the results of the final operation.
|
||||
*
|
||||
|
@ -274,7 +266,6 @@ class Recipe {
|
|||
dish.set(output, this.lastRunOp.presentType);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the recipe configuration in string format.
|
||||
*
|
||||
|
@ -284,7 +275,6 @@ class Recipe {
|
|||
return JSON.stringify(this.config);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates a Recipe from a given configuration string.
|
||||
*
|
||||
|
@ -295,7 +285,6 @@ class Recipe {
|
|||
this._parseConfig(recipeConfig);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Generates a list of all the highlight functions assigned to operations in the recipe, if the
|
||||
* entire recipe supports highlighting.
|
||||
|
@ -329,7 +318,6 @@ class Recipe {
|
|||
return highlights;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Determines whether the previous operation has a different presentation type to its normal output.
|
||||
*
|
||||
|
@ -338,9 +326,8 @@ class Recipe {
|
|||
*/
|
||||
lastOpPresented(progress) {
|
||||
if (progress < 1) return false;
|
||||
return this.opList[progress-1].presentType !== this.opList[progress-1].outputType;
|
||||
return this.opList[progress - 1].presentType !== this.opList[progress - 1].outputType;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default Recipe;
|
||||
|
|
|
@ -7,16 +7,15 @@
|
|||
// loglevel import required for Node API
|
||||
import log from "loglevel";
|
||||
import utf8 from "utf8";
|
||||
import {fromBase64, toBase64} from "./lib/Base64.mjs";
|
||||
import {fromHex} from "./lib/Hex.mjs";
|
||||
import {fromDecimal} from "./lib/Decimal.mjs";
|
||||
import {fromBinary} from "./lib/Binary.mjs";
|
||||
import { fromBase64, toBase64 } from "./lib/Base64.mjs";
|
||||
import { fromHex } from "./lib/Hex.mjs";
|
||||
import { fromDecimal } from "./lib/Decimal.mjs";
|
||||
import { fromBinary } from "./lib/Binary.mjs";
|
||||
|
||||
/**
|
||||
* Utility functions for use in operations, the core framework and the stage.
|
||||
*/
|
||||
class Utils {
|
||||
|
||||
/**
|
||||
* Translates an ordinal into a character.
|
||||
*
|
||||
|
@ -33,15 +32,14 @@ class Utils {
|
|||
// https://mathiasbynens.be/notes/javascript-unicode
|
||||
if (o > 0xffff) {
|
||||
o -= 0x10000;
|
||||
const high = String.fromCharCode(o >>> 10 & 0x3ff | 0xd800);
|
||||
o = 0xdc00 | o & 0x3ff;
|
||||
const high = String.fromCharCode(((o >>> 10) & 0x3ff) | 0xd800);
|
||||
o = 0xdc00 | (o & 0x3ff);
|
||||
return high + String.fromCharCode(o);
|
||||
}
|
||||
|
||||
return String.fromCharCode(o);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Translates a character into an ordinal.
|
||||
*
|
||||
|
@ -59,8 +57,7 @@ class Utils {
|
|||
if (c.length === 2) {
|
||||
const high = c.charCodeAt(0);
|
||||
const low = c.charCodeAt(1);
|
||||
if (high >= 0xd800 && high < 0xdc00 &&
|
||||
low >= 0xdc00 && low < 0xe000) {
|
||||
if (high >= 0xd800 && high < 0xdc00 && low >= 0xdc00 && low < 0xe000) {
|
||||
return (high - 0xd800) * 0x400 + low - 0xdc00 + 0x10000;
|
||||
}
|
||||
}
|
||||
|
@ -68,7 +65,6 @@ class Utils {
|
|||
return c.charCodeAt(0);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Adds trailing bytes to a byteArray.
|
||||
*
|
||||
|
@ -92,7 +88,7 @@ class Utils {
|
|||
* // returns ["t", "e", "s", "t", 1, 1, 1, 1]
|
||||
* Utils.padBytesRight("test", 8, 1);
|
||||
*/
|
||||
static padBytesRight(arr, numBytes, padByte=0) {
|
||||
static padBytesRight(arr, numBytes, padByte = 0) {
|
||||
const paddedBytes = new Array(numBytes);
|
||||
paddedBytes.fill(padByte);
|
||||
|
||||
|
@ -103,7 +99,6 @@ class Utils {
|
|||
return paddedBytes;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Truncates a long string to max length and adds suffix.
|
||||
*
|
||||
|
@ -119,14 +114,13 @@ class Utils {
|
|||
* // returns "A long s-"
|
||||
* Utils.truncate("A long string", 9, "-");
|
||||
*/
|
||||
static truncate(str, max, suffix="...") {
|
||||
static truncate(str, max, suffix = "...") {
|
||||
if (str.length > max) {
|
||||
str = str.slice(0, max - suffix.length) + suffix;
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Converts a character or number to its hex representation.
|
||||
*
|
||||
|
@ -141,12 +135,11 @@ class Utils {
|
|||
* // returns "6e"
|
||||
* Utils.hex(110);
|
||||
*/
|
||||
static hex(c, length=2) {
|
||||
static hex(c, length = 2) {
|
||||
c = typeof c == "string" ? Utils.ord(c) : c;
|
||||
return c.toString(16).padStart(length, "0");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Converts a character or number to its binary representation.
|
||||
*
|
||||
|
@ -161,12 +154,11 @@ class Utils {
|
|||
* // returns "01101110"
|
||||
* Utils.bin(110);
|
||||
*/
|
||||
static bin(c, length=8) {
|
||||
static bin(c, length = 8) {
|
||||
c = typeof c == "string" ? Utils.ord(c) : c;
|
||||
return c.toString(2).padStart(length, "0");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a string with all non-printable chars as dots, optionally preserving whitespace.
|
||||
*
|
||||
|
@ -175,13 +167,13 @@ class Utils {
|
|||
* @param {boolean} [onlyAscii=false] - Whether or not to replace non ASCII characters.
|
||||
* @returns {string}
|
||||
*/
|
||||
static printable(str, preserveWs=false, onlyAscii=false) {
|
||||
static printable(str, preserveWs = false, onlyAscii = false) {
|
||||
if (onlyAscii) {
|
||||
return str.replace(/[^\x20-\x7f]/g, ".");
|
||||
}
|
||||
|
||||
// eslint-disable-next-line no-misleading-character-class
|
||||
const re = /[\0-\x08\x0B-\x0C\x0E-\x1F\x7F-\x9F\xAD\u0378\u0379\u037F-\u0383\u038B\u038D\u03A2\u0528-\u0530\u0557\u0558\u0560\u0588\u058B-\u058E\u0590\u05C8-\u05CF\u05EB-\u05EF\u05F5-\u0605\u061C\u061D\u06DD\u070E\u070F\u074B\u074C\u07B2-\u07BF\u07FB-\u07FF\u082E\u082F\u083F\u085C\u085D\u085F-\u089F\u08A1\u08AD-\u08E3\u08FF\u0978\u0980\u0984\u098D\u098E\u0991\u0992\u09A9\u09B1\u09B3-\u09B5\u09BA\u09BB\u09C5\u09C6\u09C9\u09CA\u09CF-\u09D6\u09D8-\u09DB\u09DE\u09E4\u09E5\u09FC-\u0A00\u0A04\u0A0B-\u0A0E\u0A11\u0A12\u0A29\u0A31\u0A34\u0A37\u0A3A\u0A3B\u0A3D\u0A43-\u0A46\u0A49\u0A4A\u0A4E-\u0A50\u0A52-\u0A58\u0A5D\u0A5F-\u0A65\u0A76-\u0A80\u0A84\u0A8E\u0A92\u0AA9\u0AB1\u0AB4\u0ABA\u0ABB\u0AC6\u0ACA\u0ACE\u0ACF\u0AD1-\u0ADF\u0AE4\u0AE5\u0AF2-\u0B00\u0B04\u0B0D\u0B0E\u0B11\u0B12\u0B29\u0B31\u0B34\u0B3A\u0B3B\u0B45\u0B46\u0B49\u0B4A\u0B4E-\u0B55\u0B58-\u0B5B\u0B5E\u0B64\u0B65\u0B78-\u0B81\u0B84\u0B8B-\u0B8D\u0B91\u0B96-\u0B98\u0B9B\u0B9D\u0BA0-\u0BA2\u0BA5-\u0BA7\u0BAB-\u0BAD\u0BBA-\u0BBD\u0BC3-\u0BC5\u0BC9\u0BCE\u0BCF\u0BD1-\u0BD6\u0BD8-\u0BE5\u0BFB-\u0C00\u0C04\u0C0D\u0C11\u0C29\u0C34\u0C3A-\u0C3C\u0C45\u0C49\u0C4E-\u0C54\u0C57\u0C5A-\u0C5F\u0C64\u0C65\u0C70-\u0C77\u0C80\u0C81\u0C84\u0C8D\u0C91\u0CA9\u0CB4\u0CBA\u0CBB\u0CC5\u0CC9\u0CCE-\u0CD4\u0CD7-\u0CDD\u0CDF\u0CE4\u0CE5\u0CF0\u0CF3-\u0D01\u0D04\u0D0D\u0D11\u0D3B\u0D3C\u0D45\u0D49\u0D4F-\u0D56\u0D58-\u0D5F\u0D64\u0D65\u0D76-\u0D78\u0D80\u0D81\u0D84\u0D97-\u0D99\u0DB2\u0DBC\u0DBE\u0DBF\u0DC7-\u0DC9\u0DCB-\u0DCE\u0DD5\u0DD7\u0DE0-\u0DF1\u0DF5-\u0E00\u0E3B-\u0E3E\u0E5C-\u0E80\u0E83\u0E85\u0E86\u0E89\u0E8B\u0E8C\u0E8E-\u0E93\u0E98\u0EA0\u0EA4\u0EA6\u0EA8\u0EA9\u0EAC\u0EBA\u0EBE\u0EBF\u0EC5\u0EC7\u0ECE\u0ECF\u0EDA\u0EDB\u0EE0-\u0EFF\u0F48\u0F6D-\u0F70\u0F98\u0FBD\u0FCD\u0FDB-\u0FFF\u10C6\u10C8-\u10CC\u10CE\u10CF\u1249\u124E\u124F\u1257\u1259\u125E\u125F\u1289\u128E\u128F\u12B1\u12B6\u12B7\u12BF\u12C1\u12C6\u12C7\u12D7\u1311\u1316\u1317\u135B\u135C\u137D-\u137F\u139A-\u139F\u13F5-\u13FF\u169D-\u169F\u16F1-\u16FF\u170D\u1715-\u171F\u1737-\u173F\u1754-\u175F\u176D\u1771\u1774-\u177F\u17DE\u17DF\u17EA-\u17EF\u17FA-\u17FF\u180F\u181A-\u181F\u1878-\u187F\u18AB-\u18AF\u18F6-\u18FF\u191D-\u191F\u192C-\u192F\u193C-\u193F\u1941-\u1943\u196E\u196F\u1975-\u197F\u19AC-\u19AF\u19CA-\u19CF\u19DB-\u19DD\u1A1C\u1A1D\u1A5F\u1A7D\u1A7E\u1A8A-\u1A8F\u1A9A-\u1A9F\u1AAE-\u1AFF\u1B4C-\u1B4F\u1B7D-\u1B7F\u1BF4-\u1BFB\u1C38-\u1C3A\u1C4A-\u1C4C\u1C80-\u1CBF\u1CC8-\u1CCF\u1CF7-\u1CFF\u1DE7-\u1DFB\u1F16\u1F17\u1F1E\u1F1F\u1F46\u1F47\u1F4E\u1F4F\u1F58\u1F5A\u1F5C\u1F5E\u1F7E\u1F7F\u1FB5\u1FC5\u1FD4\u1FD5\u1FDC\u1FF0\u1FF1\u1FF5\u1FFF\u200B-\u200F\u202A-\u202E\u2060-\u206F\u2072\u2073\u208F\u209D-\u209F\u20BB-\u20CF\u20F1-\u20FF\u218A-\u218F\u23F4-\u23FF\u2427-\u243F\u244B-\u245F\u2700\u2B4D-\u2B4F\u2B5A-\u2BFF\u2C2F\u2C5F\u2CF4-\u2CF8\u2D26\u2D28-\u2D2C\u2D2E\u2D2F\u2D68-\u2D6E\u2D71-\u2D7E\u2D97-\u2D9F\u2DA7\u2DAF\u2DB7\u2DBF\u2DC7\u2DCF\u2DD7\u2DDF\u2E3C-\u2E7F\u2E9A\u2EF4-\u2EFF\u2FD6-\u2FEF\u2FFC-\u2FFF\u3040\u3097\u3098\u3100-\u3104\u312E-\u3130\u318F\u31BB-\u31BF\u31E4-\u31EF\u321F\u32FF\u4DB6-\u4DBF\u9FCD-\u9FFF\uA48D-\uA48F\uA4C7-\uA4CF\uA62C-\uA63F\uA698-\uA69E\uA6F8-\uA6FF\uA78F\uA794-\uA79F\uA7AB-\uA7F7\uA82C-\uA82F\uA83A-\uA83F\uA878-\uA87F\uA8C5-\uA8CD\uA8DA-\uA8DF\uA8FC-\uA8FF\uA954-\uA95E\uA97D-\uA97F\uA9CE\uA9DA-\uA9DD\uA9E0-\uA9FF\uAA37-\uAA3F\uAA4E\uAA4F\uAA5A\uAA5B\uAA7C-\uAA7F\uAAC3-\uAADA\uAAF7-\uAB00\uAB07\uAB08\uAB0F\uAB10\uAB17-\uAB1F\uAB27\uAB2F-\uABBF\uABEE\uABEF\uABFA-\uABFF\uD7A4-\uD7AF\uD7C7-\uD7CA\uD7FC-\uD7FF\uE000-\uF8FF\uFA6E\uFA6F\uFADA-\uFAFF\uFB07-\uFB12\uFB18-\uFB1C\uFB37\uFB3D\uFB3F\uFB42\uFB45\uFBC2-\uFBD2\uFD40-\uFD4F\uFD90\uFD91\uFDC8-\uFDEF\uFDFE\uFDFF\uFE1A-\uFE1F\uFE27-\uFE2F\uFE53\uFE67\uFE6C-\uFE6F\uFE75\uFEFD-\uFF00\uFFBF-\uFFC1\uFFC8\uFFC9\uFFD0\uFFD1\uFFD8\uFFD9\uFFDD-\uFFDF\uFFE7\uFFEF-\uFFFB\uFFFE\uFFFF]/g;
|
||||
const re
|
||||
= /[\0-\x08\x0B-\x0C\x0E-\x1F\x7F-\x9F\xAD\u0378\u0379\u037F-\u0383\u038B\u038D\u03A2\u0528-\u0530\u0557\u0558\u0560\u0588\u058B-\u058E\u0590\u05C8-\u05CF\u05EB-\u05EF\u05F5-\u0605\u061C\u061D\u06DD\u070E\u070F\u074B\u074C\u07B2-\u07BF\u07FB-\u07FF\u082E\u082F\u083F\u085C\u085D\u085F-\u089F\u08A1\u08AD-\u08E3\u08FF\u0978\u0980\u0984\u098D\u098E\u0991\u0992\u09A9\u09B1\u09B3-\u09B5\u09BA\u09BB\u09C5\u09C6\u09C9\u09CA\u09CF-\u09D6\u09D8-\u09DB\u09DE\u09E4\u09E5\u09FC-\u0A00\u0A04\u0A0B-\u0A0E\u0A11\u0A12\u0A29\u0A31\u0A34\u0A37\u0A3A\u0A3B\u0A3D\u0A43-\u0A46\u0A49\u0A4A\u0A4E-\u0A50\u0A52-\u0A58\u0A5D\u0A5F-\u0A65\u0A76-\u0A80\u0A84\u0A8E\u0A92\u0AA9\u0AB1\u0AB4\u0ABA\u0ABB\u0AC6\u0ACA\u0ACE\u0ACF\u0AD1-\u0ADF\u0AE4\u0AE5\u0AF2-\u0B00\u0B04\u0B0D\u0B0E\u0B11\u0B12\u0B29\u0B31\u0B34\u0B3A\u0B3B\u0B45\u0B46\u0B49\u0B4A\u0B4E-\u0B55\u0B58-\u0B5B\u0B5E\u0B64\u0B65\u0B78-\u0B81\u0B84\u0B8B-\u0B8D\u0B91\u0B96-\u0B98\u0B9B\u0B9D\u0BA0-\u0BA2\u0BA5-\u0BA7\u0BAB-\u0BAD\u0BBA-\u0BBD\u0BC3-\u0BC5\u0BC9\u0BCE\u0BCF\u0BD1-\u0BD6\u0BD8-\u0BE5\u0BFB-\u0C00\u0C04\u0C0D\u0C11\u0C29\u0C34\u0C3A-\u0C3C\u0C45\u0C49\u0C4E-\u0C54\u0C57\u0C5A-\u0C5F\u0C64\u0C65\u0C70-\u0C77\u0C80\u0C81\u0C84\u0C8D\u0C91\u0CA9\u0CB4\u0CBA\u0CBB\u0CC5\u0CC9\u0CCE-\u0CD4\u0CD7-\u0CDD\u0CDF\u0CE4\u0CE5\u0CF0\u0CF3-\u0D01\u0D04\u0D0D\u0D11\u0D3B\u0D3C\u0D45\u0D49\u0D4F-\u0D56\u0D58-\u0D5F\u0D64\u0D65\u0D76-\u0D78\u0D80\u0D81\u0D84\u0D97-\u0D99\u0DB2\u0DBC\u0DBE\u0DBF\u0DC7-\u0DC9\u0DCB-\u0DCE\u0DD5\u0DD7\u0DE0-\u0DF1\u0DF5-\u0E00\u0E3B-\u0E3E\u0E5C-\u0E80\u0E83\u0E85\u0E86\u0E89\u0E8B\u0E8C\u0E8E-\u0E93\u0E98\u0EA0\u0EA4\u0EA6\u0EA8\u0EA9\u0EAC\u0EBA\u0EBE\u0EBF\u0EC5\u0EC7\u0ECE\u0ECF\u0EDA\u0EDB\u0EE0-\u0EFF\u0F48\u0F6D-\u0F70\u0F98\u0FBD\u0FCD\u0FDB-\u0FFF\u10C6\u10C8-\u10CC\u10CE\u10CF\u1249\u124E\u124F\u1257\u1259\u125E\u125F\u1289\u128E\u128F\u12B1\u12B6\u12B7\u12BF\u12C1\u12C6\u12C7\u12D7\u1311\u1316\u1317\u135B\u135C\u137D-\u137F\u139A-\u139F\u13F5-\u13FF\u169D-\u169F\u16F1-\u16FF\u170D\u1715-\u171F\u1737-\u173F\u1754-\u175F\u176D\u1771\u1774-\u177F\u17DE\u17DF\u17EA-\u17EF\u17FA-\u17FF\u180F\u181A-\u181F\u1878-\u187F\u18AB-\u18AF\u18F6-\u18FF\u191D-\u191F\u192C-\u192F\u193C-\u193F\u1941-\u1943\u196E\u196F\u1975-\u197F\u19AC-\u19AF\u19CA-\u19CF\u19DB-\u19DD\u1A1C\u1A1D\u1A5F\u1A7D\u1A7E\u1A8A-\u1A8F\u1A9A-\u1A9F\u1AAE-\u1AFF\u1B4C-\u1B4F\u1B7D-\u1B7F\u1BF4-\u1BFB\u1C38-\u1C3A\u1C4A-\u1C4C\u1C80-\u1CBF\u1CC8-\u1CCF\u1CF7-\u1CFF\u1DE7-\u1DFB\u1F16\u1F17\u1F1E\u1F1F\u1F46\u1F47\u1F4E\u1F4F\u1F58\u1F5A\u1F5C\u1F5E\u1F7E\u1F7F\u1FB5\u1FC5\u1FD4\u1FD5\u1FDC\u1FF0\u1FF1\u1FF5\u1FFF\u200B-\u200F\u202A-\u202E\u2060-\u206F\u2072\u2073\u208F\u209D-\u209F\u20BB-\u20CF\u20F1-\u20FF\u218A-\u218F\u23F4-\u23FF\u2427-\u243F\u244B-\u245F\u2700\u2B4D-\u2B4F\u2B5A-\u2BFF\u2C2F\u2C5F\u2CF4-\u2CF8\u2D26\u2D28-\u2D2C\u2D2E\u2D2F\u2D68-\u2D6E\u2D71-\u2D7E\u2D97-\u2D9F\u2DA7\u2DAF\u2DB7\u2DBF\u2DC7\u2DCF\u2DD7\u2DDF\u2E3C-\u2E7F\u2E9A\u2EF4-\u2EFF\u2FD6-\u2FEF\u2FFC-\u2FFF\u3040\u3097\u3098\u3100-\u3104\u312E-\u3130\u318F\u31BB-\u31BF\u31E4-\u31EF\u321F\u32FF\u4DB6-\u4DBF\u9FCD-\u9FFF\uA48D-\uA48F\uA4C7-\uA4CF\uA62C-\uA63F\uA698-\uA69E\uA6F8-\uA6FF\uA78F\uA794-\uA79F\uA7AB-\uA7F7\uA82C-\uA82F\uA83A-\uA83F\uA878-\uA87F\uA8C5-\uA8CD\uA8DA-\uA8DF\uA8FC-\uA8FF\uA954-\uA95E\uA97D-\uA97F\uA9CE\uA9DA-\uA9DD\uA9E0-\uA9FF\uAA37-\uAA3F\uAA4E\uAA4F\uAA5A\uAA5B\uAA7C-\uAA7F\uAAC3-\uAADA\uAAF7-\uAB00\uAB07\uAB08\uAB0F\uAB10\uAB17-\uAB1F\uAB27\uAB2F-\uABBF\uABEE\uABEF\uABFA-\uABFF\uD7A4-\uD7AF\uD7C7-\uD7CA\uD7FC-\uD7FF\uE000-\uF8FF\uFA6E\uFA6F\uFADA-\uFAFF\uFB07-\uFB12\uFB18-\uFB1C\uFB37\uFB3D\uFB3F\uFB42\uFB45\uFBC2-\uFBD2\uFD40-\uFD4F\uFD90\uFD91\uFDC8-\uFDEF\uFDFE\uFDFF\uFE1A-\uFE1F\uFE27-\uFE2F\uFE53\uFE67\uFE6C-\uFE6F\uFE75\uFEFD-\uFF00\uFFBF-\uFFC1\uFFC8\uFFC9\uFFD0\uFFD1\uFFD8\uFFD9\uFFDD-\uFFDF\uFFE7\uFFEF-\uFFFB\uFFFE\uFFFF]/g; // eslint-disable-line no-misleading-character-class
|
||||
const wsRe = /[\x09-\x10\u2028\u2029]/g;
|
||||
|
||||
str = str.replace(re, ".");
|
||||
|
@ -189,7 +181,6 @@ class Utils {
|
|||
return str;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a string with whitespace represented as special characters from the
|
||||
* Unicode Private Use Area, which CyberChef will display as control characters.
|
||||
|
@ -199,12 +190,11 @@ class Utils {
|
|||
* @returns {string}
|
||||
*/
|
||||
static escapeWhitespace(str) {
|
||||
return str.replace(/[\x09-\x10]/g, function(c) {
|
||||
return str.replace(/[\x09-\x10]/g, function (c) {
|
||||
return String.fromCharCode(0xe000 + c.charCodeAt(0));
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Parse a string entered by a user and replace escaped chars with the bytes they represent.
|
||||
*
|
||||
|
@ -219,49 +209,49 @@ class Utils {
|
|||
* Utils.parseEscapedChars("\\n");
|
||||
*/
|
||||
static parseEscapedChars(str) {
|
||||
return str.replace(/\\([abfnrtv'"]|[0-3][0-7]{2}|[0-7]{1,2}|x[\da-fA-F]{2}|u[\da-fA-F]{4}|u\{[\da-fA-F]{1,6}\}|\\)/g, function(m, a) {
|
||||
switch (a[0]) {
|
||||
case "\\":
|
||||
return "\\";
|
||||
case "0":
|
||||
case "1":
|
||||
case "2":
|
||||
case "3":
|
||||
case "4":
|
||||
case "5":
|
||||
case "6":
|
||||
case "7":
|
||||
return String.fromCharCode(parseInt(a, 8));
|
||||
case "a":
|
||||
return String.fromCharCode(7);
|
||||
case "b":
|
||||
return "\b";
|
||||
case "t":
|
||||
return "\t";
|
||||
case "n":
|
||||
return "\n";
|
||||
case "v":
|
||||
return "\v";
|
||||
case "f":
|
||||
return "\f";
|
||||
case "r":
|
||||
return "\r";
|
||||
case '"':
|
||||
return '"';
|
||||
case "'":
|
||||
return "'";
|
||||
case "x":
|
||||
return String.fromCharCode(parseInt(a.substr(1), 16));
|
||||
case "u":
|
||||
if (a[1] === "{")
|
||||
return String.fromCodePoint(parseInt(a.slice(2, -1), 16));
|
||||
else
|
||||
return str.replace(
|
||||
/\\([abfnrtv'"]|[0-3][0-7]{2}|[0-7]{1,2}|x[\da-fA-F]{2}|u[\da-fA-F]{4}|u\{[\da-fA-F]{1,6}\}|\\)/g,
|
||||
function (m, a) {
|
||||
switch (a[0]) {
|
||||
case "\\":
|
||||
return "\\";
|
||||
case "0":
|
||||
case "1":
|
||||
case "2":
|
||||
case "3":
|
||||
case "4":
|
||||
case "5":
|
||||
case "6":
|
||||
case "7":
|
||||
return String.fromCharCode(parseInt(a, 8));
|
||||
case "a":
|
||||
return String.fromCharCode(7);
|
||||
case "b":
|
||||
return "\b";
|
||||
case "t":
|
||||
return "\t";
|
||||
case "n":
|
||||
return "\n";
|
||||
case "v":
|
||||
return "\v";
|
||||
case "f":
|
||||
return "\f";
|
||||
case "r":
|
||||
return "\r";
|
||||
case '"':
|
||||
return '"';
|
||||
case "'":
|
||||
return "'";
|
||||
case "x":
|
||||
return String.fromCharCode(parseInt(a.substr(1), 16));
|
||||
case "u":
|
||||
if (a[1] === "{") return String.fromCodePoint(parseInt(a.slice(2, -1), 16));
|
||||
else return String.fromCharCode(parseInt(a.substr(1), 16));
|
||||
}
|
||||
}
|
||||
});
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Escape a string containing regex control characters so that it can be safely
|
||||
* used in a regex without causing unintended behaviours.
|
||||
|
@ -277,7 +267,6 @@ class Utils {
|
|||
return str.replace(/([.*+?^=!:${}()|[\]/\\])/g, "\\$1");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Expand an alphabet range string into a list of the characters in that range.
|
||||
*
|
||||
|
@ -298,19 +287,15 @@ class Utils {
|
|||
const alphArr = [];
|
||||
|
||||
for (let i = 0; i < alphStr.length; i++) {
|
||||
if (i < alphStr.length - 2 &&
|
||||
alphStr[i+1] === "-" &&
|
||||
alphStr[i] !== "\\") {
|
||||
if (i < alphStr.length - 2 && alphStr[i + 1] === "-" && alphStr[i] !== "\\") {
|
||||
const start = Utils.ord(alphStr[i]),
|
||||
end = Utils.ord(alphStr[i+2]);
|
||||
end = Utils.ord(alphStr[i + 2]);
|
||||
|
||||
for (let j = start; j <= end; j++) {
|
||||
alphArr.push(Utils.chr(j));
|
||||
}
|
||||
i += 2;
|
||||
} else if (i < alphStr.length - 2 &&
|
||||
alphStr[i] === "\\" &&
|
||||
alphStr[i+1] === "-") {
|
||||
} else if (i < alphStr.length - 2 && alphStr[i] === "\\" && alphStr[i + 1] === "-") {
|
||||
alphArr.push("-");
|
||||
i++;
|
||||
} else {
|
||||
|
@ -320,7 +305,6 @@ class Utils {
|
|||
return alphArr;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Coverts data of varying types to a byteArray.
|
||||
* Accepts hex, Base64, UTF8 and Latin1 strings.
|
||||
|
@ -357,7 +341,6 @@ class Utils {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Coverts data of varying types to a byte string.
|
||||
* Accepts hex, Base64, UTF8 and Latin1 strings.
|
||||
|
@ -394,7 +377,6 @@ class Utils {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Converts a byte array to an integer.
|
||||
*
|
||||
|
@ -413,17 +395,16 @@ class Utils {
|
|||
let value = 0;
|
||||
if (byteorder === "big") {
|
||||
for (let i = 0; i < byteArray.length; i++) {
|
||||
value = (value * 256) + byteArray[i];
|
||||
value = value * 256 + byteArray[i];
|
||||
}
|
||||
} else {
|
||||
for (let i = byteArray.length - 1; i >= 0; i--) {
|
||||
value = (value * 256) + byteArray[i];
|
||||
value = value * 256 + byteArray[i];
|
||||
}
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Converts an integer to a byte array of {length} bytes.
|
||||
*
|
||||
|
@ -446,19 +427,18 @@ class Utils {
|
|||
const arr = new Array(length);
|
||||
if (byteorder === "little") {
|
||||
for (let i = 0; i < length; i++) {
|
||||
arr[i] = value & 0xFF;
|
||||
arr[i] = value & 0xff;
|
||||
value = value >>> 8;
|
||||
}
|
||||
} else {
|
||||
for (let i = length - 1; i >= 0; i--) {
|
||||
arr[i] = value & 0xFF;
|
||||
arr[i] = value & 0xff;
|
||||
value = value >>> 8;
|
||||
}
|
||||
}
|
||||
return arr;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Converts a string to an ArrayBuffer.
|
||||
* Treats the string as UTF-8 if any values are over 255.
|
||||
|
@ -475,10 +455,11 @@ class Utils {
|
|||
*/
|
||||
static strToArrayBuffer(str) {
|
||||
log.debug(`Converting string[${str?.length}] to array buffer`);
|
||||
if (!str) return new ArrayBuffer;
|
||||
if (!str) return new ArrayBuffer();
|
||||
|
||||
const arr = new Uint8Array(str.length);
|
||||
let i = str.length, b;
|
||||
let i = str.length,
|
||||
b;
|
||||
while (i--) {
|
||||
b = str.charCodeAt(i);
|
||||
arr[i] = b;
|
||||
|
@ -488,7 +469,6 @@ class Utils {
|
|||
return arr.buffer;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Converts a string to a UTF-8 ArrayBuffer.
|
||||
*
|
||||
|
@ -504,7 +484,7 @@ class Utils {
|
|||
*/
|
||||
static strToUtf8ArrayBuffer(str) {
|
||||
log.debug(`Converting string[${str?.length}] to UTF8 array buffer`);
|
||||
if (!str) return new ArrayBuffer;
|
||||
if (!str) return new ArrayBuffer();
|
||||
|
||||
const buffer = new TextEncoder("utf-8").encode(str);
|
||||
|
||||
|
@ -519,7 +499,6 @@ class Utils {
|
|||
return buffer.buffer;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Converts a string to a byte array.
|
||||
* Treats the string as UTF-8 if any values are over 255.
|
||||
|
@ -538,7 +517,8 @@ class Utils {
|
|||
log.debug(`Converting string[${str?.length}] to byte array`);
|
||||
if (!str) return [];
|
||||
const byteArray = new Array(str.length);
|
||||
let i = str.length, b;
|
||||
let i = str.length,
|
||||
b;
|
||||
while (i--) {
|
||||
b = str.charCodeAt(i);
|
||||
byteArray[i] = b;
|
||||
|
@ -548,7 +528,6 @@ class Utils {
|
|||
return byteArray;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Converts a string to a UTF-8 byte array.
|
||||
*
|
||||
|
@ -578,7 +557,6 @@ class Utils {
|
|||
return Utils.strToByteArray(utf8Str);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Converts a string to a unicode charcode array
|
||||
*
|
||||
|
@ -614,7 +592,6 @@ class Utils {
|
|||
return charcode;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Attempts to convert a byte array to a UTF-8 string.
|
||||
*
|
||||
|
@ -631,11 +608,10 @@ class Utils {
|
|||
static byteArrayToUtf8(byteArray) {
|
||||
log.debug(`Converting byte array[${byteArray?.length}] to UTF8`);
|
||||
if (!byteArray || !byteArray.length) return "";
|
||||
if (!(byteArray instanceof Uint8Array))
|
||||
byteArray = new Uint8Array(byteArray);
|
||||
if (!(byteArray instanceof Uint8Array)) byteArray = new Uint8Array(byteArray);
|
||||
|
||||
try {
|
||||
const str = new TextDecoder("utf-8", {fatal: true}).decode(byteArray);
|
||||
const str = new TextDecoder("utf-8", { fatal: true }).decode(byteArray);
|
||||
|
||||
if (str.length !== byteArray.length) {
|
||||
if (isWorkerEnvironment()) {
|
||||
|
@ -652,7 +628,6 @@ class Utils {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Converts a charcode array to a string.
|
||||
*
|
||||
|
@ -673,12 +648,11 @@ class Utils {
|
|||
// Maxiumum arg length for fromCharCode is 65535, but the stack may already be fairly deep,
|
||||
// so don't get too near it.
|
||||
for (let i = 0; i < byteArray.length; i += 20000) {
|
||||
str += String.fromCharCode(...(byteArray.slice(i, i+20000)));
|
||||
str += String.fromCharCode(...byteArray.slice(i, i + 20000));
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Converts an ArrayBuffer to a string.
|
||||
*
|
||||
|
@ -690,7 +664,7 @@ class Utils {
|
|||
* // returns "hello"
|
||||
* Utils.arrayBufferToStr(Uint8Array.from([104,101,108,108,111]).buffer);
|
||||
*/
|
||||
static arrayBufferToStr(arrayBuffer, utf8=true) {
|
||||
static arrayBufferToStr(arrayBuffer, utf8 = true) {
|
||||
log.debug(`Converting array buffer[${arrayBuffer?.byteLength}] to str`);
|
||||
if (!arrayBuffer || !arrayBuffer.byteLength) return "";
|
||||
const arr = new Uint8Array(arrayBuffer);
|
||||
|
@ -729,13 +703,12 @@ class Utils {
|
|||
|
||||
for (i = 0; i < prob.length; i++) {
|
||||
p = prob[i];
|
||||
entropy += p * Math.log(p) / Math.log(2);
|
||||
entropy += (p * Math.log(p)) / Math.log(2);
|
||||
}
|
||||
|
||||
return -entropy;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Parses CSV data and returns it as a two dimensional array or strings.
|
||||
*
|
||||
|
@ -748,7 +721,7 @@ class Utils {
|
|||
* // returns [["head1", "head2"], ["data1", "data2"]]
|
||||
* Utils.parseCSV("head1,head2\ndata1,data2");
|
||||
*/
|
||||
static parseCSV(data, cellDelims=[","], lineDelims=["\n", "\r"]) {
|
||||
static parseCSV(data, cellDelims = [","], lineDelims = ["\n", "\r"]) {
|
||||
let b,
|
||||
next,
|
||||
renderNext = false,
|
||||
|
@ -762,14 +735,14 @@ class Utils {
|
|||
|
||||
for (let i = 0; i < data.length; i++) {
|
||||
b = data[i];
|
||||
next = data[i+1] || "";
|
||||
next = data[i + 1] || "";
|
||||
if (renderNext) {
|
||||
cell += b;
|
||||
renderNext = false;
|
||||
} else if (b === "\"" && !inString) {
|
||||
} else if (b === '"' && !inString) {
|
||||
inString = true;
|
||||
} else if (b === "\"" && inString) {
|
||||
if (next === "\"") renderNext = true;
|
||||
} else if (b === '"' && inString) {
|
||||
if (next === '"') renderNext = true;
|
||||
else inString = false;
|
||||
} else if (!inString && cellDelims.indexOf(b) >= 0) {
|
||||
line.push(cell);
|
||||
|
@ -796,7 +769,6 @@ class Utils {
|
|||
return lines;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Removes all HTML (or XML) tags from the input string.
|
||||
*
|
||||
|
@ -809,7 +781,7 @@ class Utils {
|
|||
* // returns "Test"
|
||||
* Utils.stripHtmlTags("<div>Test</div>");
|
||||
*/
|
||||
static stripHtmlTags(htmlStr, removeScriptAndStyle=false) {
|
||||
static stripHtmlTags(htmlStr, removeScriptAndStyle = false) {
|
||||
/**
|
||||
* Recursively remove a pattern from a string until there are no more matches.
|
||||
* Avoids incomplete sanitization e.g. "aabcbc".replace(/abc/g, "") === "abc"
|
||||
|
@ -830,7 +802,6 @@ class Utils {
|
|||
return recursiveRemove(/<[^>]+>/g, htmlStr);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Escapes HTML tags in a string to stop them being rendered.
|
||||
* https://www.owasp.org/index.php/XSS_(Cross_Site_Scripting)_Prevention_Cheat_Sheet
|
||||
|
@ -858,12 +829,13 @@ class Utils {
|
|||
"\u0000": "\ue000"
|
||||
};
|
||||
|
||||
return str ? str.replace(/[&<>"'`\u0000]/g, function (match) {
|
||||
return HTML_CHARS[match];
|
||||
}) : str;
|
||||
return str
|
||||
? str.replace(/[&<>"'`\u0000]/g, function (match) {
|
||||
return HTML_CHARS[match];
|
||||
})
|
||||
: str;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Unescapes HTML tags in a string to make them render again.
|
||||
*
|
||||
|
@ -876,9 +848,9 @@ class Utils {
|
|||
*/
|
||||
static unescapeHtml(str) {
|
||||
const HTML_CHARS = {
|
||||
"&": "&",
|
||||
"<": "<",
|
||||
">": ">",
|
||||
"&": "&",
|
||||
"<": "<",
|
||||
">": ">",
|
||||
""": '"',
|
||||
"'": "'",
|
||||
"/": "/",
|
||||
|
@ -886,12 +858,11 @@ class Utils {
|
|||
"\ue000": "\u0000"
|
||||
};
|
||||
|
||||
return str.replace(/(&#?x?[a-z0-9]{2,4};|\ue000)/ig, function (match) {
|
||||
return str.replace(/(&#?x?[a-z0-9]{2,4};|\ue000)/gi, function (match) {
|
||||
return HTML_CHARS[match] || match;
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Converts a string to it's title case equivalent.
|
||||
*
|
||||
|
@ -903,12 +874,11 @@ class Utils {
|
|||
* Utils.toTitleCase("a tIny String");
|
||||
*/
|
||||
static toTitleCase(str) {
|
||||
return str.replace(/\w\S*/g, function(txt) {
|
||||
return str.replace(/\w\S*/g, function (txt) {
|
||||
return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase();
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Encodes a URI fragment (#) or query (?) using a minimal amount of percent-encoding.
|
||||
*
|
||||
|
@ -960,7 +930,6 @@ class Utils {
|
|||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Generates a "pretty" recipe format from a recipeConfig object.
|
||||
*
|
||||
|
@ -982,7 +951,7 @@ class Utils {
|
|||
disabled = "",
|
||||
bp = "";
|
||||
|
||||
recipeConfig.forEach(op => {
|
||||
recipeConfig.forEach((op) => {
|
||||
name = op.op.replace(/ /g, "_");
|
||||
args = JSON.stringify(op.args)
|
||||
.slice(1, -1) // Remove [ and ] as they are implied
|
||||
|
@ -992,7 +961,7 @@ class Utils {
|
|||
.replace(/"((?:[^"\\]|\\.)*)"/g, "'$1'") // Replace opening and closing " with '
|
||||
.replace(/\\"/g, '"'); // Unescape double quotes
|
||||
|
||||
disabled = op.disabled ? "/disabled": "";
|
||||
disabled = op.disabled ? "/disabled" : "";
|
||||
bp = op.breakpoint ? "/breakpoint" : "";
|
||||
prettyConfig += `${name}(${args}${disabled}${bp})`;
|
||||
if (newline) prettyConfig += "\n";
|
||||
|
@ -1000,7 +969,6 @@ class Utils {
|
|||
return prettyConfig;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Converts a recipe string to the JSON representation of the recipe.
|
||||
* Accepts either stringified JSON or the bespoke "pretty" recipe format.
|
||||
|
@ -1039,7 +1007,6 @@ class Utils {
|
|||
return recipeConfig;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Formats a list of files or directories.
|
||||
*
|
||||
|
@ -1050,7 +1017,7 @@ class Utils {
|
|||
* @returns {html}
|
||||
*/
|
||||
static async displayFilesAsHTML(files) {
|
||||
const formatDirectory = function(file) {
|
||||
const formatDirectory = function (file) {
|
||||
const html = `<div class='card' style='white-space: normal;'>
|
||||
<div class='card-header'>
|
||||
<h6 class="mb-0">
|
||||
|
@ -1072,12 +1039,9 @@ class Utils {
|
|||
}
|
||||
};
|
||||
|
||||
const formatFile = async function(file, i) {
|
||||
const formatFile = async function (file, i) {
|
||||
const buff = await Utils.readFile(file);
|
||||
const blob = new Blob(
|
||||
[buff],
|
||||
{type: file.type || "octet/stream"}
|
||||
);
|
||||
const blob = new Blob([buff], { type: file.type || "octet/stream" });
|
||||
const blobURL = URL.createObjectURL(blob);
|
||||
|
||||
const html = `<div class='card' style='white-space: normal;'>
|
||||
|
@ -1130,10 +1094,9 @@ class Utils {
|
|||
}
|
||||
}
|
||||
|
||||
return html += "</div>";
|
||||
return (html += "</div>");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Parses URI parameters into a JSON object.
|
||||
*
|
||||
|
@ -1149,8 +1112,7 @@ class Utils {
|
|||
if (paramStr === "") return {};
|
||||
|
||||
// Cut off ? or # and split on &
|
||||
if (paramStr[0] === "?" ||
|
||||
paramStr[0] === "#") {
|
||||
if (paramStr[0] === "?" || paramStr[0] === "#") {
|
||||
paramStr = paramStr.substr(1);
|
||||
}
|
||||
|
||||
|
@ -1169,7 +1131,6 @@ class Utils {
|
|||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Reads a File and returns the data as a Uint8Array.
|
||||
*
|
||||
|
@ -1181,10 +1142,8 @@ class Utils {
|
|||
* await Utils.readFile(new File(["hello"], "test"))
|
||||
*/
|
||||
static readFile(file) {
|
||||
|
||||
if (isNodeEnvironment()) {
|
||||
return Buffer.from(file).buffer;
|
||||
|
||||
} else {
|
||||
return new Promise((resolve, reject) => {
|
||||
const reader = new FileReader();
|
||||
|
@ -1192,7 +1151,7 @@ class Utils {
|
|||
let offset = 0;
|
||||
const CHUNK_SIZE = 10485760; // 10MiB
|
||||
|
||||
const seek = function() {
|
||||
const seek = function () {
|
||||
if (offset >= file.size) {
|
||||
resolve(data);
|
||||
return;
|
||||
|
@ -1201,13 +1160,13 @@ class Utils {
|
|||
reader.readAsArrayBuffer(slice);
|
||||
};
|
||||
|
||||
reader.onload = function(e) {
|
||||
reader.onload = function (e) {
|
||||
data.set(new Uint8Array(reader.result), offset);
|
||||
offset += CHUNK_SIZE;
|
||||
seek();
|
||||
};
|
||||
|
||||
reader.onerror = function(e) {
|
||||
reader.onerror = function (e) {
|
||||
reject(reader.error.message);
|
||||
};
|
||||
|
||||
|
@ -1234,7 +1193,6 @@ class Utils {
|
|||
return arrayBuffer.buffer;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Actual modulo function, since % is actually the remainder function in JS.
|
||||
*
|
||||
|
@ -1247,7 +1205,6 @@ class Utils {
|
|||
return ((x % y) + y) % y;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Finds the greatest common divisor of two numbers.
|
||||
*
|
||||
|
@ -1263,7 +1220,6 @@ class Utils {
|
|||
return Utils.gcd(y, x % y);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Finds the modular inverse of two values.
|
||||
*
|
||||
|
@ -1281,7 +1237,6 @@ class Utils {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* A mapping of names of delimiter characters to their symbols.
|
||||
*
|
||||
|
@ -1290,24 +1245,23 @@ class Utils {
|
|||
*/
|
||||
static charRep(token) {
|
||||
return {
|
||||
"Space": " ",
|
||||
"Percent": "%",
|
||||
"Comma": ",",
|
||||
"Semi-colon": ";",
|
||||
"Colon": ":",
|
||||
"Tab": "\t",
|
||||
"Line feed": "\n",
|
||||
"CRLF": "\r\n",
|
||||
"Space": " ",
|
||||
"Percent": "%",
|
||||
"Comma": ",",
|
||||
"Semi-colon": ";",
|
||||
"Colon": ":",
|
||||
"Tab": "\t",
|
||||
"Line feed": "\n",
|
||||
"CRLF": "\r\n",
|
||||
"Forward slash": "/",
|
||||
"Backslash": "\\",
|
||||
"0x": "0x",
|
||||
"\\x": "\\x",
|
||||
"Backslash": "\\",
|
||||
"0x": "0x",
|
||||
"\\x": "\\x",
|
||||
"Nothing (separate chars)": "",
|
||||
"None": "",
|
||||
"None": ""
|
||||
}[token];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* A mapping of names of delimiter characters to regular expressions which can select them.
|
||||
*
|
||||
|
@ -1316,19 +1270,19 @@ class Utils {
|
|||
*/
|
||||
static regexRep(token) {
|
||||
return {
|
||||
"Space": /\s+/g,
|
||||
"Percent": /%/g,
|
||||
"Comma": /,/g,
|
||||
"Semi-colon": /;/g,
|
||||
"Colon": /:/g,
|
||||
"Line feed": /\n/g,
|
||||
"CRLF": /\r\n/g,
|
||||
"Space": /\s+/g,
|
||||
"Percent": /%/g,
|
||||
"Comma": /,/g,
|
||||
"Semi-colon": /;/g,
|
||||
"Colon": /:/g,
|
||||
"Line feed": /\n/g,
|
||||
"CRLF": /\r\n/g,
|
||||
"Forward slash": /\//g,
|
||||
"Backslash": /\\/g,
|
||||
"Backslash": /\\/g,
|
||||
"0x with comma": /,?0x/g,
|
||||
"0x": /0x/g,
|
||||
"\\x": /\\x/g,
|
||||
"None": /\s+/g // Included here to remove whitespace when there shouldn't be any
|
||||
"0x": /0x/g,
|
||||
"\\x": /\\x/g,
|
||||
"None": /\s+/g // Included here to remove whitespace when there shouldn't be any
|
||||
}[token];
|
||||
}
|
||||
|
||||
|
@ -1338,7 +1292,7 @@ class Utils {
|
|||
* @param {Iterable} iterable
|
||||
* @param {number} chunksize
|
||||
*/
|
||||
static* chunked(iterable, chunksize) {
|
||||
static *chunked(iterable, chunksize) {
|
||||
const iterator = iterable[Symbol.iterator]();
|
||||
while (true) {
|
||||
const res = [];
|
||||
|
@ -1369,7 +1323,7 @@ export function isNodeEnvironment() {
|
|||
/**
|
||||
* Check whether the code is running in a web environment
|
||||
* @returns {boolean}
|
||||
*/
|
||||
*/
|
||||
export function isWebEnvironment() {
|
||||
return typeof window === "object";
|
||||
}
|
||||
|
@ -1377,14 +1331,13 @@ export function isWebEnvironment() {
|
|||
/**
|
||||
* Check whether the code is running in a worker
|
||||
* @returns {boolean}
|
||||
*/
|
||||
*/
|
||||
export function isWorkerEnvironment() {
|
||||
return typeof importScripts === "function";
|
||||
}
|
||||
|
||||
export default Utils;
|
||||
|
||||
|
||||
/**
|
||||
* Removes all duplicates from an array.
|
||||
*
|
||||
|
@ -1397,8 +1350,9 @@ export default Utils;
|
|||
* // returns ["One", "Two", "Three"]
|
||||
* ["One", "Two", "Three", "One"].unique();
|
||||
*/
|
||||
Array.prototype.unique = function() {
|
||||
const u = {}, a = [];
|
||||
Array.prototype.unique = function () {
|
||||
const u = {},
|
||||
a = [];
|
||||
for (let i = 0, l = this.length; i < l; i++) {
|
||||
if (Object.prototype.hasOwnProperty.call(u, this[i])) {
|
||||
continue;
|
||||
|
@ -1409,7 +1363,6 @@ Array.prototype.unique = function() {
|
|||
return a;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns the largest value in the array.
|
||||
*
|
||||
|
@ -1419,11 +1372,10 @@ Array.prototype.unique = function() {
|
|||
* // returns 7
|
||||
* [4,2,5,3,7].max();
|
||||
*/
|
||||
Array.prototype.max = function() {
|
||||
Array.prototype.max = function () {
|
||||
return Math.max.apply(null, this);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns the smallest value in the array.
|
||||
*
|
||||
|
@ -1433,11 +1385,10 @@ Array.prototype.max = function() {
|
|||
* // returns 2
|
||||
* [4,2,5,3,7].min();
|
||||
*/
|
||||
Array.prototype.min = function() {
|
||||
Array.prototype.min = function () {
|
||||
return Math.min.apply(null, this);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Sums all the values in an array.
|
||||
*
|
||||
|
@ -1447,13 +1398,12 @@ Array.prototype.min = function() {
|
|||
* // returns 21
|
||||
* [4,2,5,3,7].sum();
|
||||
*/
|
||||
Array.prototype.sum = function() {
|
||||
Array.prototype.sum = function () {
|
||||
return this.reduce(function (a, b) {
|
||||
return a + b;
|
||||
}, 0);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Determine whether two arrays are equal or not.
|
||||
*
|
||||
|
@ -1467,7 +1417,7 @@ Array.prototype.sum = function() {
|
|||
* // returns false
|
||||
* [1,2,3].equals([3,2,1]);
|
||||
*/
|
||||
Array.prototype.equals = function(other) {
|
||||
Array.prototype.equals = function (other) {
|
||||
if (!other) return false;
|
||||
let i = this.length;
|
||||
if (i !== other.length) return false;
|
||||
|
@ -1477,7 +1427,6 @@ Array.prototype.equals = function(other) {
|
|||
return true;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Counts the number of times a char appears in a string.
|
||||
*
|
||||
|
@ -1488,21 +1437,18 @@ Array.prototype.equals = function(other) {
|
|||
* // returns 2
|
||||
* "Hello".count("l");
|
||||
*/
|
||||
String.prototype.count = function(chr) {
|
||||
String.prototype.count = function (chr) {
|
||||
return this.split(chr).length - 1;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Wrapper for self.sendStatusMessage to handle different environments.
|
||||
*
|
||||
* @param {string} msg
|
||||
*/
|
||||
export function sendStatusMessage(msg) {
|
||||
if (isWorkerEnvironment())
|
||||
self.sendStatusMessage(msg);
|
||||
else if (isWebEnvironment())
|
||||
app.alert(msg, 10000);
|
||||
if (isWorkerEnvironment()) self.sendStatusMessage(msg);
|
||||
else if (isWebEnvironment()) app.alert(msg, 10000);
|
||||
else if (isNodeEnvironment() && !global.TESTING)
|
||||
// eslint-disable-next-line no-console
|
||||
console.debug(msg);
|
||||
|
@ -1523,8 +1469,8 @@ const debounceTimeouts = {};
|
|||
* @returns {function}
|
||||
*/
|
||||
export function debounce(func, wait, id, scope, args) {
|
||||
return function() {
|
||||
const later = function() {
|
||||
return function () {
|
||||
const later = function () {
|
||||
func.apply(scope, args);
|
||||
};
|
||||
clearTimeout(debounceTimeouts[id]);
|
||||
|
@ -1532,7 +1478,6 @@ export function debounce(func, wait, id, scope, args) {
|
|||
};
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Polyfills
|
||||
*/
|
||||
|
@ -1541,33 +1486,32 @@ export function debounce(func, wait, id, scope, args) {
|
|||
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/padStart
|
||||
if (!String.prototype.padStart) {
|
||||
String.prototype.padStart = function padStart(targetLength, padString) {
|
||||
targetLength = targetLength>>0; // floor if number or convert non-number to 0;
|
||||
padString = String((typeof padString !== "undefined" ? padString : " "));
|
||||
targetLength = targetLength >> 0; // floor if number or convert non-number to 0;
|
||||
padString = String(typeof padString !== "undefined" ? padString : " ");
|
||||
if (this.length > targetLength) {
|
||||
return String(this);
|
||||
} else {
|
||||
targetLength = targetLength-this.length;
|
||||
targetLength = targetLength - this.length;
|
||||
if (targetLength > padString.length) {
|
||||
padString += padString.repeat(targetLength/padString.length); // append to original to ensure we are longer than needed
|
||||
padString += padString.repeat(targetLength / padString.length); // append to original to ensure we are longer than needed
|
||||
}
|
||||
return padString.slice(0, targetLength) + String(this);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
// https://github.com/uxitten/polyfill/blob/master/string.polyfill.js
|
||||
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/padEnd
|
||||
if (!String.prototype.padEnd) {
|
||||
String.prototype.padEnd = function padEnd(targetLength, padString) {
|
||||
targetLength = targetLength>>0; // floor if number or convert non-number to 0;
|
||||
padString = String((typeof padString !== "undefined" ? padString : " "));
|
||||
targetLength = targetLength >> 0; // floor if number or convert non-number to 0;
|
||||
padString = String(typeof padString !== "undefined" ? padString : " ");
|
||||
if (this.length > targetLength) {
|
||||
return String(this);
|
||||
} else {
|
||||
targetLength = targetLength-this.length;
|
||||
targetLength = targetLength - this.length;
|
||||
if (targetLength > padString.length) {
|
||||
padString += padString.repeat(targetLength/padString.length); // append to original to ensure we are longer than needed
|
||||
padString += padString.repeat(targetLength / padString.length); // append to original to ensure we are longer than needed
|
||||
}
|
||||
return String(this) + padString.slice(0, targetLength);
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
/* eslint no-console: ["off"] */
|
||||
|
||||
import path from "path";
|
||||
import fs from "fs";
|
||||
import fs from "fs";
|
||||
import process from "process";
|
||||
import * as Ops from "../../operations/index.mjs";
|
||||
|
||||
|
@ -24,7 +24,6 @@ if (!fs.existsSync(dir)) {
|
|||
process.exit(1);
|
||||
}
|
||||
|
||||
|
||||
const operationConfig = {},
|
||||
modules = {};
|
||||
|
||||
|
@ -35,33 +34,27 @@ for (const opObj in Ops) {
|
|||
const op = new Ops[opObj]();
|
||||
|
||||
operationConfig[op.name] = {
|
||||
module: op.module,
|
||||
module: op.module,
|
||||
description: op.description,
|
||||
infoURL: op.infoURL,
|
||||
inputType: op.inputType,
|
||||
outputType: op.presentType,
|
||||
infoURL: op.infoURL,
|
||||
inputType: op.inputType,
|
||||
outputType: op.presentType,
|
||||
flowControl: op.flowControl,
|
||||
manualBake: op.manualBake,
|
||||
args: op.args,
|
||||
checks: op.checks
|
||||
manualBake: op.manualBake,
|
||||
args: op.args,
|
||||
checks: op.checks
|
||||
};
|
||||
|
||||
if (!(op.module in modules))
|
||||
modules[op.module] = {};
|
||||
if (!(op.module in modules)) modules[op.module] = {};
|
||||
modules[op.module][op.name] = opObj;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Write OperationConfig.
|
||||
*/
|
||||
fs.writeFileSync(
|
||||
path.join(dir, "OperationConfig.json"),
|
||||
JSON.stringify(operationConfig, null, 4)
|
||||
);
|
||||
fs.writeFileSync(path.join(dir, "OperationConfig.json"), JSON.stringify(operationConfig, null, 4));
|
||||
console.log("Written OperationConfig.json");
|
||||
|
||||
|
||||
/**
|
||||
* Write modules.
|
||||
*/
|
||||
|
@ -98,14 +91,10 @@ OpModules.${module} = {
|
|||
|
||||
export default OpModules;
|
||||
`;
|
||||
fs.writeFileSync(
|
||||
path.join(dir, `modules/${module}.mjs`),
|
||||
code
|
||||
);
|
||||
fs.writeFileSync(path.join(dir, `modules/${module}.mjs`), code);
|
||||
console.log(`Written ${module} module`);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Write OpModules wrapper.
|
||||
*/
|
||||
|
@ -140,8 +129,5 @@ opModulesCode += `);
|
|||
export default OpModules;
|
||||
`;
|
||||
|
||||
fs.writeFileSync(
|
||||
path.join(dir, "modules/OpModules.mjs"),
|
||||
opModulesCode
|
||||
);
|
||||
fs.writeFileSync(path.join(dir, "modules/OpModules.mjs"), opModulesCode);
|
||||
console.log("Written OpModules.mjs");
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
/* eslint no-console: ["off"] */
|
||||
|
||||
import path from "path";
|
||||
import fs from "fs";
|
||||
import fs from "fs";
|
||||
import process from "process";
|
||||
|
||||
const dir = path.join(process.cwd() + "/src/core/config/");
|
||||
|
@ -23,7 +23,7 @@ if (!fs.existsSync(dir)) {
|
|||
|
||||
// Find all operation files
|
||||
const opObjs = [];
|
||||
fs.readdirSync(path.join(dir, "../operations")).forEach(file => {
|
||||
fs.readdirSync(path.join(dir, "../operations")).forEach((file) => {
|
||||
if (!file.endsWith(".mjs") || file === "index.mjs") return;
|
||||
opObjs.push(file.split(".mjs")[0]);
|
||||
});
|
||||
|
@ -38,7 +38,7 @@ let code = `/**
|
|||
*/
|
||||
`;
|
||||
|
||||
opObjs.forEach(obj => {
|
||||
opObjs.forEach((obj) => {
|
||||
code += `import ${obj} from "./${obj}.mjs";\n`;
|
||||
});
|
||||
|
||||
|
@ -46,15 +46,12 @@ code += `
|
|||
export {
|
||||
`;
|
||||
|
||||
opObjs.forEach(obj => {
|
||||
opObjs.forEach((obj) => {
|
||||
code += ` ${obj},\n`;
|
||||
});
|
||||
|
||||
code += "};\n";
|
||||
|
||||
// Write file
|
||||
fs.writeFileSync(
|
||||
path.join(dir, "../operations/index.mjs"),
|
||||
code
|
||||
);
|
||||
fs.writeFileSync(path.join(dir, "../operations/index.mjs"), code);
|
||||
console.log("Written operation index.");
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
import prompt from "prompt";
|
||||
import colors from "colors";
|
||||
import path from "path";
|
||||
import fs from "fs";
|
||||
import fs from "fs";
|
||||
import process from "process";
|
||||
|
||||
const dir = path.join(process.cwd() + "/src/core/config/");
|
||||
|
@ -24,16 +24,12 @@ if (!fs.existsSync(dir)) {
|
|||
|
||||
let changelogData = fs.readFileSync(path.join(process.cwd(), "CHANGELOG.md"), "utf8");
|
||||
const lastVersion = changelogData.match(/## Details\s+### \[(\d+)\.(\d+)\.(\d+)\]/);
|
||||
const newVersion = [
|
||||
parseInt(lastVersion[1], 10),
|
||||
parseInt(lastVersion[2], 10) + 1,
|
||||
0
|
||||
];
|
||||
const newVersion = [parseInt(lastVersion[1], 10), parseInt(lastVersion[2], 10) + 1, 0];
|
||||
|
||||
let knownContributors = changelogData.match(/^\[@([^\]]+)\]/gm);
|
||||
knownContributors = knownContributors.map(c => c.slice(2, -1));
|
||||
knownContributors = knownContributors.map((c) => c.slice(2, -1));
|
||||
|
||||
const date = (new Date()).toISOString().split("T")[0];
|
||||
const date = new Date().toISOString().split("T")[0];
|
||||
|
||||
const schema = {
|
||||
properties: {
|
||||
|
@ -42,7 +38,7 @@ const schema = {
|
|||
example: "Added 'Op name' operation",
|
||||
prompt: "Feature description",
|
||||
type: "string",
|
||||
required: true,
|
||||
required: true
|
||||
},
|
||||
author: {
|
||||
description: "The author of the feature (only one supported, edit manually to add more)",
|
||||
|
@ -62,7 +58,7 @@ const schema = {
|
|||
example: "y",
|
||||
prompt: "Add another feature?",
|
||||
type: "string",
|
||||
pattern: /^[yn]$/,
|
||||
pattern: /^[yn]$/
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -70,7 +66,8 @@ const schema = {
|
|||
// Build schema
|
||||
for (const prop in schema.properties) {
|
||||
const p = schema.properties[prop];
|
||||
p.description = "\n" + colors.white(p.description) + colors.cyan("\nExample: " + p.example) + "\n" + colors.green(p.prompt);
|
||||
p.description
|
||||
= "\n" + colors.white(p.description) + colors.cyan("\nExample: " + p.example) + "\n" + colors.green(p.prompt);
|
||||
}
|
||||
|
||||
prompt.message = "";
|
||||
|
@ -83,7 +80,7 @@ const commitIDs = [];
|
|||
|
||||
prompt.start();
|
||||
|
||||
const getFeature = function() {
|
||||
const getFeature = function () {
|
||||
prompt.get(schema, (err, result) => {
|
||||
if (err) {
|
||||
console.log("\nExiting script.");
|
||||
|
@ -97,7 +94,7 @@ const getFeature = function() {
|
|||
} else {
|
||||
let message = `### [${newVersion[0]}.${newVersion[1]}.${newVersion[2]}] - ${date}\n`;
|
||||
|
||||
features.forEach(feature => {
|
||||
features.forEach((feature) => {
|
||||
const id = feature.id.length > 10 ? feature.id.slice(0, 7) : "#" + feature.id;
|
||||
message += `- ${feature.message} [@${feature.author}] | [${id}]\n`;
|
||||
|
||||
|
@ -120,18 +117,27 @@ const getFeature = function() {
|
|||
changelogData = changelogData.replace(/\n\n(\[\d+\.\d+\.\d+\]: https)/, "\n\n" + newTag + "$1");
|
||||
|
||||
// Author
|
||||
authors.forEach(author => {
|
||||
changelogData = changelogData.replace(/(\n\[@[^\]]+\]: https:\/\/github\.com\/[^\n]+\n)\n/, "$1" + author + "\n\n");
|
||||
authors.forEach((author) => {
|
||||
changelogData = changelogData.replace(
|
||||
/(\n\[@[^\]]+\]: https:\/\/github\.com\/[^\n]+\n)\n/,
|
||||
"$1" + author + "\n\n"
|
||||
);
|
||||
});
|
||||
|
||||
// Commit IDs
|
||||
commitIDs.forEach(commitID => {
|
||||
changelogData = changelogData.replace(/(\n\[[^\].]+\]: https:\/\/github.com\/gchq\/CyberChef\/commit\/[^\n]+\n)\n/, "$1" + commitID + "\n\n");
|
||||
commitIDs.forEach((commitID) => {
|
||||
changelogData = changelogData.replace(
|
||||
/(\n\[[^\].]+\]: https:\/\/github.com\/gchq\/CyberChef\/commit\/[^\n]+\n)\n/,
|
||||
"$1" + commitID + "\n\n"
|
||||
);
|
||||
});
|
||||
|
||||
// PR IDs
|
||||
prIDs.forEach(prID => {
|
||||
changelogData = changelogData.replace(/(\n\[#[^\]]+\]: https:\/\/github.com\/gchq\/CyberChef\/pull\/[^\n]+\n)\n*$/, "$1" + prID + "\n\n");
|
||||
prIDs.forEach((prID) => {
|
||||
changelogData = changelogData.replace(
|
||||
/(\n\[#[^\]]+\]: https:\/\/github.com\/gchq\/CyberChef\/pull\/[^\n]+\n)\n*$/,
|
||||
"$1" + prID + "\n\n"
|
||||
);
|
||||
});
|
||||
|
||||
fs.writeFileSync(path.join(process.cwd(), "CHANGELOG.md"), changelogData);
|
||||
|
|
|
@ -15,7 +15,6 @@ import fs from "fs";
|
|||
import path from "path";
|
||||
import EscapeString from "../../operations/EscapeString.mjs";
|
||||
|
||||
|
||||
const dir = path.join(process.cwd() + "/src/core/operations/");
|
||||
if (!fs.existsSync(dir)) {
|
||||
console.log("\nCWD: " + process.cwd());
|
||||
|
@ -48,16 +47,19 @@ If your operation does not rely on a library, just leave this blank and it will
|
|||
default: "Default"
|
||||
},
|
||||
description: {
|
||||
description: "The description should explain what the operation is and how it works. It can describe how the arguments should be entered and give examples of expected input and output. HTML markup is supported. Use <code> tags for examples. The description is scanned during searches, so include terms that are likely to be searched for when someone is looking for your operation.",
|
||||
example: "Converts URI/URL percent-encoded characters back to their raw values.<br><br>e.g. <code>%3d</code> becomes <code>=</code>",
|
||||
description:
|
||||
"The description should explain what the operation is and how it works. It can describe how the arguments should be entered and give examples of expected input and output. HTML markup is supported. Use <code> tags for examples. The description is scanned during searches, so include terms that are likely to be searched for when someone is looking for your operation.",
|
||||
example:
|
||||
"Converts URI/URL percent-encoded characters back to their raw values.<br><br>e.g. <code>%3d</code> becomes <code>=</code>",
|
||||
prompt: "Description",
|
||||
type: "string"
|
||||
},
|
||||
infoURL: {
|
||||
description: "An optional URL for an external site can be added to give more information about the operation. Wikipedia links are often suitable. If linking to Wikipedia, use an international link (e.g. https://wikipedia.org/...) rather than a localised link (e.g. https://en.wikipedia.org/...).",
|
||||
description:
|
||||
"An optional URL for an external site can be added to give more information about the operation. Wikipedia links are often suitable. If linking to Wikipedia, use an international link (e.g. https://wikipedia.org/...) rather than a localised link (e.g. https://en.wikipedia.org/...).",
|
||||
example: "https://wikipedia.org/wiki/Percent-encoding",
|
||||
prompt: "Information URL",
|
||||
type: "string",
|
||||
type: "string"
|
||||
},
|
||||
inputType: {
|
||||
description: `The input type defines how the input data will be presented to your operation. Check the project wiki for a full description of each type. The options are: ${ioTypes.join(", ")}.`,
|
||||
|
@ -78,7 +80,8 @@ If your operation does not rely on a library, just leave this blank and it will
|
|||
message: `The output type should be one of: ${ioTypes.join(", ")}.`
|
||||
},
|
||||
highlight: {
|
||||
description: "If your operation does not change the length of the input in any way, we can enable highlighting. If it does change the length in a predictable way, we may still be able to enable highlighting and calculate the correct offsets. If this is not possible, we will disable highlighting for this operation.",
|
||||
description:
|
||||
"If your operation does not change the length of the input in any way, we can enable highlighting. If it does change the length in a predictable way, we may still be able to enable highlighting and calculate the correct offsets. If this is not possible, we will disable highlighting for this operation.",
|
||||
example: "true/false",
|
||||
prompt: "Enable highlighting",
|
||||
type: "boolean",
|
||||
|
@ -103,10 +106,14 @@ If your operation does not rely on a library, just leave this blank and it will
|
|||
// Build schema
|
||||
for (const prop in schema.properties) {
|
||||
const p = schema.properties[prop];
|
||||
p.description = "\n" + colors.white(p.description) + colors.cyan("\nExample: " + p.example) + "\n" + colors.green(p.prompt);
|
||||
p.description
|
||||
= "\n" + colors.white(p.description) + colors.cyan("\nExample: " + p.example) + "\n" + colors.green(p.prompt);
|
||||
}
|
||||
|
||||
console.log("\n\nThis script will generate a new operation template based on the information you provide. These values can be changed manually later.".yellow);
|
||||
console.log(
|
||||
"\n\nThis script will generate a new operation template based on the information you provide. These values can be changed manually later."
|
||||
.yellow
|
||||
);
|
||||
|
||||
prompt.message = "";
|
||||
prompt.delimiter = ":".green;
|
||||
|
@ -119,14 +126,15 @@ prompt.get(schema, (err, result) => {
|
|||
process.exit(0);
|
||||
}
|
||||
|
||||
const moduleName = result.opName.replace(/\w\S*/g, txt => {
|
||||
return txt.charAt(0).toUpperCase() + txt.substr(1);
|
||||
}).replace(/[\s-()./]/g, "");
|
||||
|
||||
const moduleName = result.opName
|
||||
.replace(/\w\S*/g, (txt) => {
|
||||
return txt.charAt(0).toUpperCase() + txt.substr(1);
|
||||
})
|
||||
.replace(/[\s-()./]/g, "");
|
||||
|
||||
const template = `/**
|
||||
* @author ${result.authorName} [${result.authorEmail}]
|
||||
* @copyright Crown Copyright ${(new Date()).getFullYear()}
|
||||
* @copyright Crown Copyright ${new Date().getFullYear()}
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
|
||||
|
@ -146,7 +154,7 @@ class ${moduleName} extends Operation {
|
|||
|
||||
this.name = "${result.opName}";
|
||||
this.module = "${result.module}";
|
||||
this.description = "${(new EscapeString).run(result.description, ["Special chars", "Double"])}";
|
||||
this.description = "${new EscapeString().run(result.description, ["Special chars", "Double"])}";
|
||||
this.infoURL = "${result.infoURL}";
|
||||
this.inputType = "${result.inputType}";
|
||||
this.outputType = "${result.outputType}";
|
||||
|
@ -176,7 +184,9 @@ class ${moduleName} extends Operation {
|
|||
|
||||
throw new OperationError("Test");
|
||||
}
|
||||
${result.highlight ? `
|
||||
${
|
||||
result.highlight
|
||||
? `
|
||||
/**
|
||||
* Highlight ${result.opName}
|
||||
*
|
||||
|
@ -202,7 +212,9 @@ ${result.highlight ? `
|
|||
highlightReverse(pos, args) {
|
||||
return pos;
|
||||
}
|
||||
` : ""}
|
||||
`
|
||||
: ""
|
||||
}
|
||||
}
|
||||
|
||||
export default ${moduleName};
|
||||
|
@ -225,6 +237,4 @@ export default ${moduleName};
|
|||
3. Write tests in ${colors.green("tests/operations/tests/")}
|
||||
4. Run ${colors.cyan("npm run lint")} and ${colors.cyan("npm run test")}
|
||||
5. Submit a Pull Request to get your operation added to the official CyberChef repository.`);
|
||||
|
||||
});
|
||||
|
||||
|
|
|
@ -12,14 +12,15 @@ import BigNumber from "bignumber.js";
|
|||
* translation methods for BigNumber Dishes
|
||||
*/
|
||||
class DishBigNumber extends DishType {
|
||||
|
||||
/**
|
||||
* convert the given value to a ArrayBuffer
|
||||
* @param {BigNumber} value
|
||||
*/
|
||||
static toArrayBuffer() {
|
||||
DishBigNumber.checkForValue(this.value);
|
||||
this.value = BigNumber.isBigNumber(this.value) ? Utils.strToArrayBuffer(this.value.toFixed()) : new ArrayBuffer;
|
||||
this.value = BigNumber.isBigNumber(this.value)
|
||||
? Utils.strToArrayBuffer(this.value.toFixed())
|
||||
: new ArrayBuffer();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -10,7 +10,6 @@ import DishType from "./DishType.mjs";
|
|||
* Translation methods for ArrayBuffer Dishes
|
||||
*/
|
||||
class DishByteArray extends DishType {
|
||||
|
||||
/**
|
||||
* convert the given value to a ArrayBuffer
|
||||
*/
|
||||
|
|
|
@ -11,7 +11,6 @@ import Utils, { isNodeEnvironment } from "../Utils.mjs";
|
|||
* Translation methods for file Dishes
|
||||
*/
|
||||
class DishFile extends DishType {
|
||||
|
||||
/**
|
||||
* convert the given value to an ArrayBuffer
|
||||
* @param {File} value
|
||||
|
@ -23,7 +22,7 @@ class DishFile extends DishType {
|
|||
} else {
|
||||
return new Promise((resolve, reject) => {
|
||||
Utils.readFile(this.value)
|
||||
.then(v => this.value = v.buffer)
|
||||
.then((v) => (this.value = v.buffer))
|
||||
.then(resolve)
|
||||
.catch(reject);
|
||||
});
|
||||
|
|
|
@ -11,16 +11,16 @@ import Utils from "../Utils.mjs";
|
|||
* Translation methods for HTML Dishes
|
||||
*/
|
||||
class DishHTML extends DishString {
|
||||
|
||||
/**
|
||||
* convert the given value to a ArrayBuffer
|
||||
* @param {String} value
|
||||
*/
|
||||
static toArrayBuffer() {
|
||||
DishHTML.checkForValue(this.value);
|
||||
this.value = this.value ? Utils.strToArrayBuffer(Utils.unescapeHtml(Utils.stripHtmlTags(this.value, true))) : new ArrayBuffer;
|
||||
this.value = this.value
|
||||
? Utils.strToArrayBuffer(Utils.unescapeHtml(Utils.stripHtmlTags(this.value, true)))
|
||||
: new ArrayBuffer();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default DishHTML;
|
||||
|
|
|
@ -11,13 +11,13 @@ import Utils from "../Utils.mjs";
|
|||
* Translation methods for JSON dishes
|
||||
*/
|
||||
class DishJSON extends DishType {
|
||||
|
||||
/**
|
||||
* convert the given value to a ArrayBuffer
|
||||
*/
|
||||
static toArrayBuffer() {
|
||||
DishJSON.checkForValue(this.value);
|
||||
this.value = this.value !== undefined ? Utils.strToArrayBuffer(JSON.stringify(this.value, null, 4)) : new ArrayBuffer;
|
||||
this.value
|
||||
= this.value !== undefined ? Utils.strToArrayBuffer(JSON.stringify(this.value, null, 4)) : new ArrayBuffer();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -7,12 +7,10 @@
|
|||
import DishType from "./DishType.mjs";
|
||||
import Utils, { isNodeEnvironment } from "../Utils.mjs";
|
||||
|
||||
|
||||
/**
|
||||
* Translation methods for ListFile Dishes
|
||||
*/
|
||||
class DishListFile extends DishType {
|
||||
|
||||
/**
|
||||
* convert the given value to a ArrayBuffer
|
||||
*/
|
||||
|
@ -20,7 +18,7 @@ class DishListFile extends DishType {
|
|||
DishListFile.checkForValue(this.value);
|
||||
|
||||
if (isNodeEnvironment()) {
|
||||
this.value = this.value.map(file => Uint8Array.from(file.data));
|
||||
this.value = this.value.map((file) => Uint8Array.from(file.data));
|
||||
} else {
|
||||
this.value = await DishListFile.concatenateTypedArraysWithTypedElements(...this.value);
|
||||
}
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
* @license Apache-2.0
|
||||
*/
|
||||
|
||||
|
||||
import DishType from "./DishType.mjs";
|
||||
import Utils from "../Utils.mjs";
|
||||
|
||||
|
@ -12,13 +11,12 @@ import Utils from "../Utils.mjs";
|
|||
* Translation methods for number dishes
|
||||
*/
|
||||
class DishNumber extends DishType {
|
||||
|
||||
/**
|
||||
* convert the given value to a ArrayBuffer
|
||||
*/
|
||||
static toArrayBuffer() {
|
||||
DishNumber.checkForValue(this.value);
|
||||
this.value = typeof this.value === "number" ? Utils.strToArrayBuffer(this.value.toString()) : new ArrayBuffer;
|
||||
this.value = typeof this.value === "number" ? Utils.strToArrayBuffer(this.value.toString()) : new ArrayBuffer();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
* @license Apache-2.0
|
||||
*/
|
||||
|
||||
|
||||
import DishType from "./DishType.mjs";
|
||||
import Utils from "../Utils.mjs";
|
||||
|
||||
|
@ -12,13 +11,12 @@ import Utils from "../Utils.mjs";
|
|||
* Translation methods for string dishes
|
||||
*/
|
||||
class DishString extends DishType {
|
||||
|
||||
/**
|
||||
* convert the given value to a ArrayBuffer
|
||||
*/
|
||||
static toArrayBuffer() {
|
||||
DishString.checkForValue(this.value);
|
||||
this.value = this.value ? Utils.strToArrayBuffer(this.value) : new ArrayBuffer;
|
||||
this.value = this.value ? Utils.strToArrayBuffer(this.value) : new ArrayBuffer();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -4,12 +4,10 @@
|
|||
* @license Apache-2.0
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Abstract class for dish translation methods
|
||||
*/
|
||||
class DishType {
|
||||
|
||||
/**
|
||||
* Warn translations dont work without value from bind
|
||||
*/
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
* @license Apache-2.0
|
||||
*/
|
||||
|
||||
|
||||
import DishByteArray from "./DishByteArray.mjs";
|
||||
import DishBigNumber from "./DishBigNumber.mjs";
|
||||
import DishFile from "./DishFile.mjs";
|
||||
|
@ -14,13 +13,4 @@ import DishListFile from "./DishListFile.mjs";
|
|||
import DishNumber from "./DishNumber.mjs";
|
||||
import DishString from "./DishString.mjs";
|
||||
|
||||
export {
|
||||
DishByteArray,
|
||||
DishBigNumber,
|
||||
DishFile,
|
||||
DishHTML,
|
||||
DishJSON,
|
||||
DishListFile,
|
||||
DishNumber,
|
||||
DishString,
|
||||
};
|
||||
export { DishByteArray, DishBigNumber, DishFile, DishHTML, DishJSON, DishListFile, DishNumber, DishString };
|
||||
|
|
|
@ -2,8 +2,4 @@ import OperationError from "./OperationError.mjs";
|
|||
import DishError from "./DishError.mjs";
|
||||
import ExcludedOperationError from "./ExcludedOperationError.mjs";
|
||||
|
||||
export {
|
||||
OperationError,
|
||||
DishError,
|
||||
ExcludedOperationError,
|
||||
};
|
||||
export { OperationError, DishError, ExcludedOperationError };
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
import Utils from "../Utils.mjs";
|
||||
import BigNumber from "bignumber.js";
|
||||
|
||||
|
||||
/**
|
||||
* Converts a string array to a number array.
|
||||
*
|
||||
|
@ -35,7 +34,6 @@ export function createNumArray(input, delim) {
|
|||
return numbers;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Adds an array of numbers and returns the value.
|
||||
*
|
||||
|
@ -48,7 +46,6 @@ export function sum(data) {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Subtracts an array of numbers and returns the value.
|
||||
*
|
||||
|
@ -61,7 +58,6 @@ export function sub(data) {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Multiplies an array of numbers and returns the value.
|
||||
*
|
||||
|
@ -74,7 +70,6 @@ export function multi(data) {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Divides an array of numbers and returns the value.
|
||||
*
|
||||
|
@ -87,7 +82,6 @@ export function div(data) {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Computes mean of a number array and returns the value.
|
||||
*
|
||||
|
@ -100,7 +94,6 @@ export function mean(data) {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Computes median of a number array and returns the value.
|
||||
*
|
||||
|
@ -108,8 +101,8 @@ export function mean(data) {
|
|||
* @returns {BigNumber}
|
||||
*/
|
||||
export function median(data) {
|
||||
if ((data.length % 2) === 0 && data.length > 0) {
|
||||
data.sort(function(a, b) {
|
||||
if (data.length % 2 === 0 && data.length > 0) {
|
||||
data.sort(function (a, b) {
|
||||
return a.minus(b);
|
||||
});
|
||||
const first = data[Math.floor(data.length / 2)];
|
||||
|
@ -120,7 +113,6 @@ export function median(data) {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Computes standard deviation of a number array and returns the value.
|
||||
*
|
||||
|
|
|
@ -9,15 +9,7 @@
|
|||
/**
|
||||
* BCD encoding schemes.
|
||||
*/
|
||||
export const ENCODING_SCHEME = [
|
||||
"8 4 2 1",
|
||||
"7 4 2 1",
|
||||
"4 2 2 1",
|
||||
"2 4 2 1",
|
||||
"8 4 -2 -1",
|
||||
"Excess-3",
|
||||
"IBM 8 4 2 1",
|
||||
];
|
||||
export const ENCODING_SCHEME = ["8 4 2 1", "7 4 2 1", "4 2 2 1", "2 4 2 1", "8 4 -2 -1", "Excess-3", "IBM 8 4 2 1"];
|
||||
|
||||
/**
|
||||
* Lookup table for the binary value of each digit representation.
|
||||
|
@ -33,13 +25,13 @@ export const ENCODING_SCHEME = [
|
|||
* has not yet been added for this.
|
||||
*/
|
||||
export const ENCODING_LOOKUP = {
|
||||
"8 4 2 1": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
|
||||
"7 4 2 1": [0, 1, 2, 3, 4, 5, 6, 8, 9, 10],
|
||||
"4 2 2 1": [0, 1, 4, 5, 8, 9, 12, 13, 14, 15],
|
||||
"2 4 2 1": [0, 1, 2, 3, 4, 11, 12, 13, 14, 15],
|
||||
"8 4 -2 -1": [0, 7, 6, 5, 4, 11, 10, 9, 8, 15],
|
||||
"Excess-3": [3, 4, 5, 6, 7, 8, 9, 10, 11, 12],
|
||||
"IBM 8 4 2 1": [10, 1, 2, 3, 4, 5, 6, 7, 8, 9],
|
||||
"8 4 2 1": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
|
||||
"7 4 2 1": [0, 1, 2, 3, 4, 5, 6, 8, 9, 10],
|
||||
"4 2 2 1": [0, 1, 4, 5, 8, 9, 12, 13, 14, 15],
|
||||
"2 4 2 1": [0, 1, 2, 3, 4, 11, 12, 13, 14, 15],
|
||||
"8 4 -2 -1": [0, 7, 6, 5, 4, 11, 10, 9, 8, 15],
|
||||
"Excess-3": [3, 4, 5, 6, 7, 8, 9, 10, 11, 12],
|
||||
"IBM 8 4 2 1": [10, 1, 2, 3, 4, 5, 6, 7, 8, 9]
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -26,16 +26,13 @@ export const BACON_TRANSLATIONS = [
|
|||
BACON_TRANSLATION_01,
|
||||
BACON_TRANSLATION_AB,
|
||||
BACON_TRANSLATION_CASE,
|
||||
BACON_TRANSLATION_AMNZ,
|
||||
];
|
||||
export const BACON_TRANSLATIONS_FOR_ENCODING = [
|
||||
BACON_TRANSLATION_01,
|
||||
BACON_TRANSLATION_AB
|
||||
BACON_TRANSLATION_AMNZ
|
||||
];
|
||||
export const BACON_TRANSLATIONS_FOR_ENCODING = [BACON_TRANSLATION_01, BACON_TRANSLATION_AB];
|
||||
export const BACON_CLEARER_MAP = {
|
||||
[BACON_TRANSLATION_01]: /[^01]/g,
|
||||
[BACON_TRANSLATION_AB]: /[^ABab]/g,
|
||||
[BACON_TRANSLATION_CASE]: /[^A-Za-z]/g,
|
||||
[BACON_TRANSLATION_CASE]: /[^A-Za-z]/g
|
||||
};
|
||||
export const BACON_NORMALIZE_MAP = {
|
||||
[BACON_TRANSLATION_AB]: {
|
||||
|
@ -43,7 +40,7 @@ export const BACON_NORMALIZE_MAP = {
|
|||
"B": "1",
|
||||
"a": "0",
|
||||
"b": "1"
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -13,10 +13,10 @@
|
|||
export const ALPHABET_OPTIONS = [
|
||||
{
|
||||
name: "Bitcoin",
|
||||
value: "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz",
|
||||
value: "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"
|
||||
},
|
||||
{
|
||||
name: "Ripple",
|
||||
value: "rpshnaf39wBUDNEGHJKLM4PQRST7VWXYZ2bcdeCg65jkm8oFqi1tuvAxyz",
|
||||
},
|
||||
value: "rpshnaf39wBUDNEGHJKLM4PQRST7VWXYZ2bcdeCg65jkm8oFqi1tuvAxyz"
|
||||
}
|
||||
];
|
||||
|
|
|
@ -23,7 +23,7 @@ import OperationError from "../errors/OperationError.mjs";
|
|||
* // returns "SGVsbG8="
|
||||
* toBase64("Hello");
|
||||
*/
|
||||
export function toBase64(data, alphabet="A-Za-z0-9+/=") {
|
||||
export function toBase64(data, alphabet = "A-Za-z0-9+/=") {
|
||||
if (!data) return "";
|
||||
if (typeof data == "string") {
|
||||
data = Utils.strToArrayBuffer(data);
|
||||
|
@ -33,13 +33,19 @@ export function toBase64(data, alphabet="A-Za-z0-9+/=") {
|
|||
}
|
||||
|
||||
alphabet = Utils.expandAlphRange(alphabet).join("");
|
||||
if (alphabet.length !== 64 && alphabet.length !== 65) { // Allow for padding
|
||||
if (alphabet.length !== 64 && alphabet.length !== 65) {
|
||||
// Allow for padding
|
||||
throw new OperationError(`Invalid Base64 alphabet length (${alphabet.length}): ${alphabet}`);
|
||||
}
|
||||
|
||||
let output = "",
|
||||
chr1, chr2, chr3,
|
||||
enc1, enc2, enc3, enc4,
|
||||
chr1,
|
||||
chr2,
|
||||
chr3,
|
||||
enc1,
|
||||
enc2,
|
||||
enc3,
|
||||
enc4,
|
||||
i = 0;
|
||||
|
||||
while (i < data.length) {
|
||||
|
@ -58,14 +64,12 @@ export function toBase64(data, alphabet="A-Za-z0-9+/=") {
|
|||
enc4 = 64;
|
||||
}
|
||||
|
||||
output += alphabet.charAt(enc1) + alphabet.charAt(enc2) +
|
||||
alphabet.charAt(enc3) + alphabet.charAt(enc4);
|
||||
output += alphabet.charAt(enc1) + alphabet.charAt(enc2) + alphabet.charAt(enc3) + alphabet.charAt(enc4);
|
||||
}
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* UnBase64's the input string using the given alphabet, returning a byte array.
|
||||
*
|
||||
|
@ -82,7 +86,13 @@ export function toBase64(data, alphabet="A-Za-z0-9+/=") {
|
|||
* // returns [72, 101, 108, 108, 111]
|
||||
* fromBase64("SGVsbG8=", null, "byteArray");
|
||||
*/
|
||||
export function fromBase64(data, alphabet="A-Za-z0-9+/=", returnType="string", removeNonAlphChars=true, strictMode=false) {
|
||||
export function fromBase64(
|
||||
data,
|
||||
alphabet = "A-Za-z0-9+/=",
|
||||
returnType = "string",
|
||||
removeNonAlphChars = true,
|
||||
strictMode = false
|
||||
) {
|
||||
if (!data) {
|
||||
return returnType === "string" ? "" : [];
|
||||
}
|
||||
|
@ -91,8 +101,11 @@ export function fromBase64(data, alphabet="A-Za-z0-9+/=", returnType="string", r
|
|||
alphabet = Utils.expandAlphRange(alphabet).join("");
|
||||
|
||||
// Confirm alphabet is a valid length
|
||||
if (alphabet.length !== 64 && alphabet.length !== 65) { // Allow for padding
|
||||
throw new OperationError(`Error: Base64 alphabet should be 64 characters long, or 65 with a padding character. Found ${alphabet.length}: ${alphabet}`);
|
||||
if (alphabet.length !== 64 && alphabet.length !== 65) {
|
||||
// Allow for padding
|
||||
throw new OperationError(
|
||||
`Error: Base64 alphabet should be 64 characters long, or 65 with a padding character. Found ${alphabet.length}: ${alphabet}`
|
||||
);
|
||||
}
|
||||
|
||||
// Remove non-alphabet characters
|
||||
|
@ -104,10 +117,13 @@ export function fromBase64(data, alphabet="A-Za-z0-9+/=", returnType="string", r
|
|||
if (strictMode) {
|
||||
// Check for incorrect lengths (even without padding)
|
||||
if (data.length % 4 === 1) {
|
||||
throw new OperationError(`Error: Invalid Base64 input length (${data.length}). Cannot be 4n+1, even without padding chars.`);
|
||||
throw new OperationError(
|
||||
`Error: Invalid Base64 input length (${data.length}). Cannot be 4n+1, even without padding chars.`
|
||||
);
|
||||
}
|
||||
|
||||
if (alphabet.length === 65) { // Padding character included
|
||||
if (alphabet.length === 65) {
|
||||
// Padding character included
|
||||
const pad = alphabet.charAt(64);
|
||||
const padPos = data.indexOf(pad);
|
||||
if (padPos >= 0) {
|
||||
|
@ -125,8 +141,13 @@ export function fromBase64(data, alphabet="A-Za-z0-9+/=", returnType="string", r
|
|||
}
|
||||
|
||||
const output = [];
|
||||
let chr1, chr2, chr3,
|
||||
enc1, enc2, enc3, enc4,
|
||||
let chr1,
|
||||
chr2,
|
||||
chr3,
|
||||
enc1,
|
||||
enc2,
|
||||
enc3,
|
||||
enc4,
|
||||
i = 0;
|
||||
|
||||
while (i < data.length) {
|
||||
|
@ -158,26 +179,37 @@ export function fromBase64(data, alphabet="A-Za-z0-9+/=", returnType="string", r
|
|||
return returnType === "string" ? Utils.byteArrayToUtf8(output) : output;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Base64 alphabets.
|
||||
*/
|
||||
export const ALPHABET_OPTIONS = [
|
||||
{name: "Standard (RFC 4648): A-Za-z0-9+/=", value: "A-Za-z0-9+/="},
|
||||
{name: "URL safe (RFC 4648 \u00A75): A-Za-z0-9-_", value: "A-Za-z0-9-_"},
|
||||
{name: "Filename safe: A-Za-z0-9+-=", value: "A-Za-z0-9+\\-="},
|
||||
{name: "itoa64: ./0-9A-Za-z=", value: "./0-9A-Za-z="},
|
||||
{name: "XML: A-Za-z0-9_.", value: "A-Za-z0-9_."},
|
||||
{name: "y64: A-Za-z0-9._-", value: "A-Za-z0-9._-"},
|
||||
{name: "z64: 0-9a-zA-Z+/=", value: "0-9a-zA-Z+/="},
|
||||
{name: "Radix-64 (RFC 4880): 0-9A-Za-z+/=", value: "0-9A-Za-z+/="},
|
||||
{name: "Uuencoding: [space]-_", value: " -_"},
|
||||
{name: "Xxencoding: +-0-9A-Za-z", value: "+\\-0-9A-Za-z"},
|
||||
{name: "BinHex: !-,-0-689@A-NP-VX-Z[`a-fh-mp-r", value: "!-,-0-689@A-NP-VX-Z[`a-fh-mp-r"},
|
||||
{name: "ROT13: N-ZA-Mn-za-m0-9+/=", value: "N-ZA-Mn-za-m0-9+/="},
|
||||
{name: "UNIX crypt: ./0-9A-Za-z", value: "./0-9A-Za-z"},
|
||||
{name: "Atom128: /128GhIoPQROSTeUbADfgHijKLM+n0pFWXY456xyzB7=39VaqrstJklmNuZvwcdEC", value: "/128GhIoPQROSTeUbADfgHijKLM+n0pFWXY456xyzB7=39VaqrstJklmNuZvwcdEC"},
|
||||
{name: "Megan35: 3GHIJKLMNOPQRSTUb=cdefghijklmnopWXYZ/12+406789VaqrstuvwxyzABCDEF5", value: "3GHIJKLMNOPQRSTUb=cdefghijklmnopWXYZ/12+406789VaqrstuvwxyzABCDEF5"},
|
||||
{name: "Zong22: ZKj9n+yf0wDVX1s/5YbdxSo=ILaUpPBCHg8uvNO4klm6iJGhQ7eFrWczAMEq3RTt2", value: "ZKj9n+yf0wDVX1s/5YbdxSo=ILaUpPBCHg8uvNO4klm6iJGhQ7eFrWczAMEq3RTt2"},
|
||||
{name: "Hazz15: HNO4klm6ij9n+J2hyf0gzA8uvwDEq3X1Q7ZKeFrWcVTts/MRGYbdxSo=ILaUpPBC5", value: "HNO4klm6ij9n+J2hyf0gzA8uvwDEq3X1Q7ZKeFrWcVTts/MRGYbdxSo=ILaUpPBC5"}
|
||||
{ name: "Standard (RFC 4648): A-Za-z0-9+/=", value: "A-Za-z0-9+/=" },
|
||||
{ name: "URL safe (RFC 4648 \u00A75): A-Za-z0-9-_", value: "A-Za-z0-9-_" },
|
||||
{ name: "Filename safe: A-Za-z0-9+-=", value: "A-Za-z0-9+\\-=" },
|
||||
{ name: "itoa64: ./0-9A-Za-z=", value: "./0-9A-Za-z=" },
|
||||
{ name: "XML: A-Za-z0-9_.", value: "A-Za-z0-9_." },
|
||||
{ name: "y64: A-Za-z0-9._-", value: "A-Za-z0-9._-" },
|
||||
{ name: "z64: 0-9a-zA-Z+/=", value: "0-9a-zA-Z+/=" },
|
||||
{ name: "Radix-64 (RFC 4880): 0-9A-Za-z+/=", value: "0-9A-Za-z+/=" },
|
||||
{ name: "Uuencoding: [space]-_", value: " -_" },
|
||||
{ name: "Xxencoding: +-0-9A-Za-z", value: "+\\-0-9A-Za-z" },
|
||||
{ name: "BinHex: !-,-0-689@A-NP-VX-Z[`a-fh-mp-r", value: "!-,-0-689@A-NP-VX-Z[`a-fh-mp-r" },
|
||||
{ name: "ROT13: N-ZA-Mn-za-m0-9+/=", value: "N-ZA-Mn-za-m0-9+/=" },
|
||||
{ name: "UNIX crypt: ./0-9A-Za-z", value: "./0-9A-Za-z" },
|
||||
{
|
||||
name: "Atom128: /128GhIoPQROSTeUbADfgHijKLM+n0pFWXY456xyzB7=39VaqrstJklmNuZvwcdEC",
|
||||
value: "/128GhIoPQROSTeUbADfgHijKLM+n0pFWXY456xyzB7=39VaqrstJklmNuZvwcdEC"
|
||||
},
|
||||
{
|
||||
name: "Megan35: 3GHIJKLMNOPQRSTUb=cdefghijklmnopWXYZ/12+406789VaqrstuvwxyzABCDEF5",
|
||||
value: "3GHIJKLMNOPQRSTUb=cdefghijklmnopWXYZ/12+406789VaqrstuvwxyzABCDEF5"
|
||||
},
|
||||
{
|
||||
name: "Zong22: ZKj9n+yf0wDVX1s/5YbdxSo=ILaUpPBCHg8uvNO4klm6iJGhQ7eFrWczAMEq3RTt2",
|
||||
value: "ZKj9n+yf0wDVX1s/5YbdxSo=ILaUpPBCHg8uvNO4klm6iJGhQ7eFrWczAMEq3RTt2"
|
||||
},
|
||||
{
|
||||
name: "Hazz15: HNO4klm6ij9n+J2hyf0gzA8uvwDEq3X1Q7ZKeFrWcVTts/MRGYbdxSo=ILaUpPBC5",
|
||||
value: "HNO4klm6ij9n+J2hyf0gzA8uvwDEq3X1Q7ZKeFrWcVTts/MRGYbdxSo=ILaUpPBC5"
|
||||
}
|
||||
];
|
||||
|
|
|
@ -14,19 +14,18 @@ import Utils from "../Utils.mjs";
|
|||
export const ALPHABET_OPTIONS = [
|
||||
{
|
||||
name: "Standard",
|
||||
value: "!-u",
|
||||
value: "!-u"
|
||||
},
|
||||
{
|
||||
name: "Z85 (ZeroMQ)",
|
||||
value: "0-9a-zA-Z.\\-:+=^!/*?&<>()[]{}@%$#",
|
||||
value: "0-9a-zA-Z.\\-:+=^!/*?&<>()[]{}@%$#"
|
||||
},
|
||||
{
|
||||
name: "IPv6",
|
||||
value: "0-9A-Za-z!#$%&()*+\\-;<=>?@^_`{|}~",
|
||||
value: "0-9A-Za-z!#$%&()*+\\-;<=>?@^_`{|}~"
|
||||
}
|
||||
];
|
||||
|
||||
|
||||
/**
|
||||
* Returns the name of the alphabet, when given the alphabet.
|
||||
*
|
||||
|
@ -37,7 +36,7 @@ export function alphabetName(alphabet) {
|
|||
alphabet = escape(alphabet);
|
||||
let name;
|
||||
|
||||
ALPHABET_OPTIONS.forEach(function(a) {
|
||||
ALPHABET_OPTIONS.forEach(function (a) {
|
||||
const expanded = Utils.expandAlphRange(a.value).join("");
|
||||
if (alphabet === escape(expanded)) name = a.name;
|
||||
});
|
||||
|
|
|
@ -18,12 +18,9 @@ export function base92Chr(val) {
|
|||
if (val < 0 || val >= 91) {
|
||||
throw new OperationError("Invalid value");
|
||||
}
|
||||
if (val === 0)
|
||||
return "!".charCodeAt(0);
|
||||
else if (val <= 61)
|
||||
return "#".charCodeAt(0) + val - 1;
|
||||
else
|
||||
return "a".charCodeAt(0) + val - 62;
|
||||
if (val === 0) return "!".charCodeAt(0);
|
||||
else if (val <= 61) return "#".charCodeAt(0) + val - 1;
|
||||
else return "a".charCodeAt(0) + val - 62;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -33,12 +30,8 @@ export function base92Chr(val) {
|
|||
* @returns {number}
|
||||
*/
|
||||
export function base92Ord(val) {
|
||||
if (val === "!")
|
||||
return 0;
|
||||
else if ("#" <= val && val <= "_")
|
||||
return val.charCodeAt(0) - "#".charCodeAt(0) + 1;
|
||||
else if ("a" <= val && val <= "}")
|
||||
return val.charCodeAt(0) - "a".charCodeAt(0) + 62;
|
||||
if (val === "!") return 0;
|
||||
else if ("#" <= val && val <= "_") return val.charCodeAt(0) - "#".charCodeAt(0) + 1;
|
||||
else if ("a" <= val && val <= "}") return val.charCodeAt(0) - "a".charCodeAt(0) + 62;
|
||||
throw new OperationError(`${val} is not a base92 character`);
|
||||
}
|
||||
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
import Utils from "../Utils.mjs";
|
||||
import OperationError from "../errors/OperationError.mjs";
|
||||
|
||||
|
||||
/**
|
||||
* Convert a byte array into a binary string.
|
||||
*
|
||||
|
@ -28,19 +27,21 @@ import OperationError from "../errors/OperationError.mjs";
|
|||
* // returns "1010:10100:11110"
|
||||
* toBinary([10,20,30], "Colon", 0);
|
||||
*/
|
||||
export function toBinary(data, delim="Space", padding=8) {
|
||||
export function toBinary(data, delim = "Space", padding = 8) {
|
||||
if (data === undefined || data === null)
|
||||
throw new OperationError("Unable to convert to binary: Empty input data enocuntered");
|
||||
|
||||
delim = Utils.charRep(delim);
|
||||
let output = "";
|
||||
|
||||
if (data.length) { // array
|
||||
if (data.length) {
|
||||
// array
|
||||
for (let i = 0; i < data.length; i++) {
|
||||
output += data[i].toString(2).padStart(padding, "0");
|
||||
if (i !== data.length - 1) output += delim;
|
||||
}
|
||||
} else if (typeof data === "number") { // Single value
|
||||
} else if (typeof data === "number") {
|
||||
// Single value
|
||||
return data.toString(2).padStart(padding, "0");
|
||||
} else {
|
||||
return "";
|
||||
|
@ -48,7 +49,6 @@ export function toBinary(data, delim="Space", padding=8) {
|
|||
return output;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Convert a binary string into a byte array.
|
||||
*
|
||||
|
@ -64,7 +64,7 @@ export function toBinary(data, delim="Space", padding=8) {
|
|||
* // returns [10,20,30]
|
||||
* fromBinary("00001010:00010100:00011110", "Colon");
|
||||
*/
|
||||
export function fromBinary(data, delim="Space", byteLen=8) {
|
||||
export function fromBinary(data, delim = "Space", byteLen = 8) {
|
||||
if (byteLen < 1 || Math.round(byteLen) !== byteLen)
|
||||
throw new OperationError("Byte length must be a positive integer");
|
||||
|
||||
|
@ -77,4 +77,3 @@ export function fromBinary(data, delim="Space", byteLen=8) {
|
|||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
* @param {string} scheme
|
||||
* @returns {byteArray}
|
||||
*/
|
||||
export function bitOp (input, key, func, nullPreserving, scheme) {
|
||||
export function bitOp(input, key, func, nullPreserving, scheme) {
|
||||
if (!key || !key.length) key = [0];
|
||||
const result = [];
|
||||
let x = null,
|
||||
|
@ -29,9 +29,7 @@ export function bitOp (input, key, func, nullPreserving, scheme) {
|
|||
o = input[i];
|
||||
x = nullPreserving && (o === 0 || o === k) ? o : func(o, k);
|
||||
result.push(x);
|
||||
if (scheme &&
|
||||
scheme !== "Standard" &&
|
||||
!(nullPreserving && (o === 0 || o === k))) {
|
||||
if (scheme && scheme !== "Standard" && !(nullPreserving && (o === 0 || o === k))) {
|
||||
switch (scheme) {
|
||||
case "Input differential":
|
||||
key[i % key.length] = o;
|
||||
|
@ -57,7 +55,6 @@ export function xor(operand, key) {
|
|||
return operand ^ key;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* NOT bitwise calculation.
|
||||
*
|
||||
|
@ -68,7 +65,6 @@ export function not(operand, _) {
|
|||
return ~operand & 0xff;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* AND bitwise calculation.
|
||||
*
|
||||
|
@ -80,7 +76,6 @@ export function and(operand, key) {
|
|||
return operand & key;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* OR bitwise calculation.
|
||||
*
|
||||
|
@ -92,7 +87,6 @@ export function or(operand, key) {
|
|||
return operand | key;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* ADD bitwise calculation.
|
||||
*
|
||||
|
@ -104,7 +98,6 @@ export function add(operand, key) {
|
|||
return (operand + key) % 256;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* SUB bitwise calculation.
|
||||
*
|
||||
|
@ -114,10 +107,9 @@ export function add(operand, key) {
|
|||
*/
|
||||
export function sub(operand, key) {
|
||||
const result = operand - key;
|
||||
return (result < 0) ? 256 + result : result;
|
||||
return result < 0 ? 256 + result : result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Delimiter options for bitwise operations
|
||||
*/
|
||||
|
|
|
@ -40,48 +40,47 @@ const crypto = {};
|
|||
|
||||
import forge from "node-forge";
|
||||
|
||||
|
||||
/* dojo-release-1.8.1/dojo/_base/lang.js.uncompressed.js */
|
||||
|
||||
const lang = {};
|
||||
lang.isString = function(it) {
|
||||
// summary:
|
||||
// Return true if it is a String
|
||||
// it: anything
|
||||
// Item to test.
|
||||
return (typeof it == "string" || it instanceof String); // Boolean
|
||||
lang.isString = function (it) {
|
||||
// summary:
|
||||
// Return true if it is a String
|
||||
// it: anything
|
||||
// Item to test.
|
||||
return typeof it == "string" || it instanceof String; // Boolean
|
||||
};
|
||||
|
||||
|
||||
/* dojo-release-1.8.1/dojo/_base/array.js.uncompressed.js */
|
||||
|
||||
const arrayUtil = {};
|
||||
arrayUtil.map = function(arr, callback, thisObject, Ctr) {
|
||||
// summary:
|
||||
// applies callback to each element of arr and returns
|
||||
// an Array with the results
|
||||
// arr: Array|String
|
||||
// the array to iterate on. If a string, operates on
|
||||
// individual characters.
|
||||
// callback: Function
|
||||
// a function is invoked with three arguments, (item, index,
|
||||
// array), and returns a value
|
||||
// thisObject: Object?
|
||||
// may be used to scope the call to callback
|
||||
// returns: Array
|
||||
// description:
|
||||
// This function corresponds to the JavaScript 1.6 Array.map() method, with one difference: when
|
||||
// run over sparse arrays, this implementation passes the "holes" in the sparse array to
|
||||
// the callback function with a value of undefined. JavaScript 1.6's map skips the holes in the sparse array.
|
||||
// For more details, see:
|
||||
// https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/map
|
||||
// example:
|
||||
// | // returns [2, 3, 4, 5]
|
||||
// | array.map([1, 2, 3, 4], function(item){ return item+1 });
|
||||
arrayUtil.map = function (arr, callback, thisObject, Ctr) {
|
||||
// summary:
|
||||
// applies callback to each element of arr and returns
|
||||
// an Array with the results
|
||||
// arr: Array|String
|
||||
// the array to iterate on. If a string, operates on
|
||||
// individual characters.
|
||||
// callback: Function
|
||||
// a function is invoked with three arguments, (item, index,
|
||||
// array), and returns a value
|
||||
// thisObject: Object?
|
||||
// may be used to scope the call to callback
|
||||
// returns: Array
|
||||
// description:
|
||||
// This function corresponds to the JavaScript 1.6 Array.map() method, with one difference: when
|
||||
// run over sparse arrays, this implementation passes the "holes" in the sparse array to
|
||||
// the callback function with a value of undefined. JavaScript 1.6's map skips the holes in the sparse array.
|
||||
// For more details, see:
|
||||
// https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/map
|
||||
// example:
|
||||
// | // returns [2, 3, 4, 5]
|
||||
// | array.map([1, 2, 3, 4], function(item){ return item+1 });
|
||||
|
||||
// TODO: why do we have a non-standard signature here? do we need "Ctr"?
|
||||
// TODO: why do we have a non-standard signature here? do we need "Ctr"?
|
||||
let i = 0;
|
||||
const l = arr && arr.length || 0, out = new (Ctr || Array)(l);
|
||||
const l = (arr && arr.length) || 0,
|
||||
out = new (Ctr || Array)(l);
|
||||
if (l && typeof arr == "string") arr = arr.split("");
|
||||
if (thisObject) {
|
||||
for (; i < l; ++i) {
|
||||
|
@ -102,239 +101,231 @@ arrayUtil.map = function(arr, callback, thisObject, Ctr) {
|
|||
* Unsigned math based on Paul Johnstone and Peter Wood patches.
|
||||
* 2005-12-08
|
||||
*/
|
||||
const boxes={
|
||||
const boxes = {
|
||||
p: [
|
||||
0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344, 0xa4093822, 0x299f31d0, 0x082efa98, 0xec4e6c89,
|
||||
0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c, 0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917,
|
||||
0x9216d5d9, 0x8979fb1b
|
||||
0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344, 0xa4093822, 0x299f31d0, 0x082efa98, 0xec4e6c89, 0x452821e6,
|
||||
0x38d01377, 0xbe5466cf, 0x34e90c6c, 0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917, 0x9216d5d9, 0x8979fb1b
|
||||
],
|
||||
s0: [
|
||||
0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7, 0xb8e1afed, 0x6a267e96, 0xba7c9045, 0xf12c7f99,
|
||||
0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16, 0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e,
|
||||
0x0d95748f, 0x728eb658, 0x718bcd58, 0x82154aee, 0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013,
|
||||
0xc5d1b023, 0x286085f0, 0xca417918, 0xb8db38ef, 0x8e79dcb0, 0x603a180e, 0x6c9e0e8b, 0xb01e8a3e,
|
||||
0xd71577c1, 0xbd314b27, 0x78af2fda, 0x55605c60, 0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440,
|
||||
0x55ca396a, 0x2aab10b6, 0xb4cc5c34, 0x1141e8ce, 0xa15486af, 0x7c72e993, 0xb3ee1411, 0x636fbc2a,
|
||||
0x2ba9c55d, 0x741831f6, 0xce5c3e16, 0x9b87931e, 0xafd6ba33, 0x6c24cf5c, 0x7a325381, 0x28958677,
|
||||
0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193, 0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032,
|
||||
0xef845d5d, 0xe98575b1, 0xdc262302, 0xeb651b88, 0x23893e81, 0xd396acc5, 0x0f6d6ff3, 0x83f44239,
|
||||
0x2e0b4482, 0xa4842004, 0x69c8f04a, 0x9e1f9b5e, 0x21c66842, 0xf6e96c9a, 0x670c9c61, 0xabd388f0,
|
||||
0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3, 0x6eef0b6c, 0x137a3be4, 0xba3bf050, 0x7efb2a98,
|
||||
0xa1f1651d, 0x39af0176, 0x66ca593e, 0x82430e88, 0x8cee8619, 0x456f9fb4, 0x7d84a5c3, 0x3b8b5ebe,
|
||||
0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6, 0x4ed3aa62, 0x363f7706, 0x1bfedf72, 0x429b023d,
|
||||
0x37d0d724, 0xd00a1248, 0xdb0fead3, 0x49f1c09b, 0x075372c9, 0x80991b7b, 0x25d479d8, 0xf6e8def7,
|
||||
0xe3fe501a, 0xb6794c3b, 0x976ce0bd, 0x04c006ba, 0xc1a94fb6, 0x409f60c4, 0x5e5c9ec2, 0x196a2463,
|
||||
0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f, 0x6dfc511f, 0x9b30952c, 0xcc814544, 0xaf5ebd09,
|
||||
0xbee3d004, 0xde334afd, 0x660f2807, 0x192e4bb3, 0xc0cba857, 0x45c8740f, 0xd20b5f39, 0xb9d3fbdb,
|
||||
0x5579c0bd, 0x1a60320a, 0xd6a100c6, 0x402c7279, 0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8,
|
||||
0x3c7516df, 0xfd616b15, 0x2f501ec8, 0xad0552ab, 0x323db5fa, 0xfd238760, 0x53317b48, 0x3e00df82,
|
||||
0x9e5c57bb, 0xca6f8ca0, 0x1a87562e, 0xdf1769db, 0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573,
|
||||
0x695b27b0, 0xbbca58c8, 0xe1ffa35d, 0xb8f011a0, 0x10fa3d98, 0xfd2183b8, 0x4afcb56c, 0x2dd1d35b,
|
||||
0x9a53e479, 0xb6f84565, 0xd28e49bc, 0x4bfb9790, 0xe1ddf2da, 0xa4cb7e33, 0x62fb1341, 0xcee4c6e8,
|
||||
0xef20cada, 0x36774c01, 0xd07e9efe, 0x2bf11fb4, 0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0,
|
||||
0xd08ed1d0, 0xafc725e0, 0x8e3c5b2f, 0x8e7594b7, 0x8ff6e2fb, 0xf2122b64, 0x8888b812, 0x900df01c,
|
||||
0x4fad5ea0, 0x688fc31c, 0xd1cff191, 0xb3a8c1ad, 0x2f2f2218, 0xbe0e1777, 0xea752dfe, 0x8b021fa1,
|
||||
0xe5a0cc0f, 0xb56f74e8, 0x18acf3d6, 0xce89e299, 0xb4a84fe0, 0xfd13e0b7, 0x7cc43b81, 0xd2ada8d9,
|
||||
0x165fa266, 0x80957705, 0x93cc7314, 0x211a1477, 0xe6ad2065, 0x77b5fa86, 0xc75442f5, 0xfb9d35cf,
|
||||
0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3, 0xae1e7e49, 0x00250e2d, 0x2071b35e, 0x226800bb, 0x57b8e0af,
|
||||
0x2464369b, 0xf009b91e, 0x5563911d, 0x59dfa6aa, 0x78c14389, 0xd95a537f, 0x207d5ba2, 0x02e5b9c5,
|
||||
0x83260376, 0x6295cfa9, 0x11c81968, 0x4e734a41, 0xb3472dca, 0x7b14a94a, 0x1b510052, 0x9a532915,
|
||||
0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400, 0x08ba6fb5, 0x571be91f, 0xf296ec6b, 0x2a0dd915,
|
||||
0xb6636521, 0xe7b9f9b6, 0xff34052e, 0xc5855664, 0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 0x6e85076a
|
||||
0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7, 0xb8e1afed, 0x6a267e96, 0xba7c9045, 0xf12c7f99, 0x24a19947,
|
||||
0xb3916cf7, 0x0801f2e2, 0x858efc16, 0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e, 0x0d95748f, 0x728eb658,
|
||||
0x718bcd58, 0x82154aee, 0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013, 0xc5d1b023, 0x286085f0, 0xca417918,
|
||||
0xb8db38ef, 0x8e79dcb0, 0x603a180e, 0x6c9e0e8b, 0xb01e8a3e, 0xd71577c1, 0xbd314b27, 0x78af2fda, 0x55605c60,
|
||||
0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440, 0x55ca396a, 0x2aab10b6, 0xb4cc5c34, 0x1141e8ce, 0xa15486af,
|
||||
0x7c72e993, 0xb3ee1411, 0x636fbc2a, 0x2ba9c55d, 0x741831f6, 0xce5c3e16, 0x9b87931e, 0xafd6ba33, 0x6c24cf5c,
|
||||
0x7a325381, 0x28958677, 0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193, 0x61d809cc, 0xfb21a991, 0x487cac60,
|
||||
0x5dec8032, 0xef845d5d, 0xe98575b1, 0xdc262302, 0xeb651b88, 0x23893e81, 0xd396acc5, 0x0f6d6ff3, 0x83f44239,
|
||||
0x2e0b4482, 0xa4842004, 0x69c8f04a, 0x9e1f9b5e, 0x21c66842, 0xf6e96c9a, 0x670c9c61, 0xabd388f0, 0x6a51a0d2,
|
||||
0xd8542f68, 0x960fa728, 0xab5133a3, 0x6eef0b6c, 0x137a3be4, 0xba3bf050, 0x7efb2a98, 0xa1f1651d, 0x39af0176,
|
||||
0x66ca593e, 0x82430e88, 0x8cee8619, 0x456f9fb4, 0x7d84a5c3, 0x3b8b5ebe, 0xe06f75d8, 0x85c12073, 0x401a449f,
|
||||
0x56c16aa6, 0x4ed3aa62, 0x363f7706, 0x1bfedf72, 0x429b023d, 0x37d0d724, 0xd00a1248, 0xdb0fead3, 0x49f1c09b,
|
||||
0x075372c9, 0x80991b7b, 0x25d479d8, 0xf6e8def7, 0xe3fe501a, 0xb6794c3b, 0x976ce0bd, 0x04c006ba, 0xc1a94fb6,
|
||||
0x409f60c4, 0x5e5c9ec2, 0x196a2463, 0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f, 0x6dfc511f, 0x9b30952c,
|
||||
0xcc814544, 0xaf5ebd09, 0xbee3d004, 0xde334afd, 0x660f2807, 0x192e4bb3, 0xc0cba857, 0x45c8740f, 0xd20b5f39,
|
||||
0xb9d3fbdb, 0x5579c0bd, 0x1a60320a, 0xd6a100c6, 0x402c7279, 0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8,
|
||||
0x3c7516df, 0xfd616b15, 0x2f501ec8, 0xad0552ab, 0x323db5fa, 0xfd238760, 0x53317b48, 0x3e00df82, 0x9e5c57bb,
|
||||
0xca6f8ca0, 0x1a87562e, 0xdf1769db, 0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573, 0x695b27b0, 0xbbca58c8,
|
||||
0xe1ffa35d, 0xb8f011a0, 0x10fa3d98, 0xfd2183b8, 0x4afcb56c, 0x2dd1d35b, 0x9a53e479, 0xb6f84565, 0xd28e49bc,
|
||||
0x4bfb9790, 0xe1ddf2da, 0xa4cb7e33, 0x62fb1341, 0xcee4c6e8, 0xef20cada, 0x36774c01, 0xd07e9efe, 0x2bf11fb4,
|
||||
0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0, 0xd08ed1d0, 0xafc725e0, 0x8e3c5b2f, 0x8e7594b7, 0x8ff6e2fb,
|
||||
0xf2122b64, 0x8888b812, 0x900df01c, 0x4fad5ea0, 0x688fc31c, 0xd1cff191, 0xb3a8c1ad, 0x2f2f2218, 0xbe0e1777,
|
||||
0xea752dfe, 0x8b021fa1, 0xe5a0cc0f, 0xb56f74e8, 0x18acf3d6, 0xce89e299, 0xb4a84fe0, 0xfd13e0b7, 0x7cc43b81,
|
||||
0xd2ada8d9, 0x165fa266, 0x80957705, 0x93cc7314, 0x211a1477, 0xe6ad2065, 0x77b5fa86, 0xc75442f5, 0xfb9d35cf,
|
||||
0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3, 0xae1e7e49, 0x00250e2d, 0x2071b35e, 0x226800bb, 0x57b8e0af, 0x2464369b,
|
||||
0xf009b91e, 0x5563911d, 0x59dfa6aa, 0x78c14389, 0xd95a537f, 0x207d5ba2, 0x02e5b9c5, 0x83260376, 0x6295cfa9,
|
||||
0x11c81968, 0x4e734a41, 0xb3472dca, 0x7b14a94a, 0x1b510052, 0x9a532915, 0xd60f573f, 0xbc9bc6e4, 0x2b60a476,
|
||||
0x81e67400, 0x08ba6fb5, 0x571be91f, 0xf296ec6b, 0x2a0dd915, 0xb6636521, 0xe7b9f9b6, 0xff34052e, 0xc5855664,
|
||||
0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 0x6e85076a
|
||||
],
|
||||
s1: [
|
||||
0x4b7a70e9, 0xb5b32944, 0xdb75092e, 0xc4192623, 0xad6ea6b0, 0x49a7df7d, 0x9cee60b8, 0x8fedb266,
|
||||
0xecaa8c71, 0x699a17ff, 0x5664526c, 0xc2b19ee1, 0x193602a5, 0x75094c29, 0xa0591340, 0xe4183a3e,
|
||||
0x3f54989a, 0x5b429d65, 0x6b8fe4d6, 0x99f73fd6, 0xa1d29c07, 0xefe830f5, 0x4d2d38e6, 0xf0255dc1,
|
||||
0x4cdd2086, 0x8470eb26, 0x6382e9c6, 0x021ecc5e, 0x09686b3f, 0x3ebaefc9, 0x3c971814, 0x6b6a70a1,
|
||||
0x687f3584, 0x52a0e286, 0xb79c5305, 0xaa500737, 0x3e07841c, 0x7fdeae5c, 0x8e7d44ec, 0x5716f2b8,
|
||||
0xb03ada37, 0xf0500c0d, 0xf01c1f04, 0x0200b3ff, 0xae0cf51a, 0x3cb574b2, 0x25837a58, 0xdc0921bd,
|
||||
0xd19113f9, 0x7ca92ff6, 0x94324773, 0x22f54701, 0x3ae5e581, 0x37c2dadc, 0xc8b57634, 0x9af3dda7,
|
||||
0xa9446146, 0x0fd0030e, 0xecc8c73e, 0xa4751e41, 0xe238cd99, 0x3bea0e2f, 0x3280bba1, 0x183eb331,
|
||||
0x4e548b38, 0x4f6db908, 0x6f420d03, 0xf60a04bf, 0x2cb81290, 0x24977c79, 0x5679b072, 0xbcaf89af,
|
||||
0xde9a771f, 0xd9930810, 0xb38bae12, 0xdccf3f2e, 0x5512721f, 0x2e6b7124, 0x501adde6, 0x9f84cd87,
|
||||
0x7a584718, 0x7408da17, 0xbc9f9abc, 0xe94b7d8c, 0xec7aec3a, 0xdb851dfa, 0x63094366, 0xc464c3d2,
|
||||
0xef1c1847, 0x3215d908, 0xdd433b37, 0x24c2ba16, 0x12a14d43, 0x2a65c451, 0x50940002, 0x133ae4dd,
|
||||
0x71dff89e, 0x10314e55, 0x81ac77d6, 0x5f11199b, 0x043556f1, 0xd7a3c76b, 0x3c11183b, 0x5924a509,
|
||||
0xf28fe6ed, 0x97f1fbfa, 0x9ebabf2c, 0x1e153c6e, 0x86e34570, 0xeae96fb1, 0x860e5e0a, 0x5a3e2ab3,
|
||||
0x771fe71c, 0x4e3d06fa, 0x2965dcb9, 0x99e71d0f, 0x803e89d6, 0x5266c825, 0x2e4cc978, 0x9c10b36a,
|
||||
0xc6150eba, 0x94e2ea78, 0xa5fc3c53, 0x1e0a2df4, 0xf2f74ea7, 0x361d2b3d, 0x1939260f, 0x19c27960,
|
||||
0x5223a708, 0xf71312b6, 0xebadfe6e, 0xeac31f66, 0xe3bc4595, 0xa67bc883, 0xb17f37d1, 0x018cff28,
|
||||
0xc332ddef, 0xbe6c5aa5, 0x65582185, 0x68ab9802, 0xeecea50f, 0xdb2f953b, 0x2aef7dad, 0x5b6e2f84,
|
||||
0x1521b628, 0x29076170, 0xecdd4775, 0x619f1510, 0x13cca830, 0xeb61bd96, 0x0334fe1e, 0xaa0363cf,
|
||||
0xb5735c90, 0x4c70a239, 0xd59e9e0b, 0xcbaade14, 0xeecc86bc, 0x60622ca7, 0x9cab5cab, 0xb2f3846e,
|
||||
0x648b1eaf, 0x19bdf0ca, 0xa02369b9, 0x655abb50, 0x40685a32, 0x3c2ab4b3, 0x319ee9d5, 0xc021b8f7,
|
||||
0x9b540b19, 0x875fa099, 0x95f7997e, 0x623d7da8, 0xf837889a, 0x97e32d77, 0x11ed935f, 0x16681281,
|
||||
0x0e358829, 0xc7e61fd6, 0x96dedfa1, 0x7858ba99, 0x57f584a5, 0x1b227263, 0x9b83c3ff, 0x1ac24696,
|
||||
0xcdb30aeb, 0x532e3054, 0x8fd948e4, 0x6dbc3128, 0x58ebf2ef, 0x34c6ffea, 0xfe28ed61, 0xee7c3c73,
|
||||
0x5d4a14d9, 0xe864b7e3, 0x42105d14, 0x203e13e0, 0x45eee2b6, 0xa3aaabea, 0xdb6c4f15, 0xfacb4fd0,
|
||||
0xc742f442, 0xef6abbb5, 0x654f3b1d, 0x41cd2105, 0xd81e799e, 0x86854dc7, 0xe44b476a, 0x3d816250,
|
||||
0xcf62a1f2, 0x5b8d2646, 0xfc8883a0, 0xc1c7b6a3, 0x7f1524c3, 0x69cb7492, 0x47848a0b, 0x5692b285,
|
||||
0x095bbf00, 0xad19489d, 0x1462b174, 0x23820e00, 0x58428d2a, 0x0c55f5ea, 0x1dadf43e, 0x233f7061,
|
||||
0x3372f092, 0x8d937e41, 0xd65fecf1, 0x6c223bdb, 0x7cde3759, 0xcbee7460, 0x4085f2a7, 0xce77326e,
|
||||
0xa6078084, 0x19f8509e, 0xe8efd855, 0x61d99735, 0xa969a7aa, 0xc50c06c2, 0x5a04abfc, 0x800bcadc,
|
||||
0x9e447a2e, 0xc3453484, 0xfdd56705, 0x0e1e9ec9, 0xdb73dbd3, 0x105588cd, 0x675fda79, 0xe3674340,
|
||||
0xc5c43465, 0x713e38d8, 0x3d28f89e, 0xf16dff20, 0x153e21e7, 0x8fb03d4a, 0xe6e39f2b, 0xdb83adf7
|
||||
0x4b7a70e9, 0xb5b32944, 0xdb75092e, 0xc4192623, 0xad6ea6b0, 0x49a7df7d, 0x9cee60b8, 0x8fedb266, 0xecaa8c71,
|
||||
0x699a17ff, 0x5664526c, 0xc2b19ee1, 0x193602a5, 0x75094c29, 0xa0591340, 0xe4183a3e, 0x3f54989a, 0x5b429d65,
|
||||
0x6b8fe4d6, 0x99f73fd6, 0xa1d29c07, 0xefe830f5, 0x4d2d38e6, 0xf0255dc1, 0x4cdd2086, 0x8470eb26, 0x6382e9c6,
|
||||
0x021ecc5e, 0x09686b3f, 0x3ebaefc9, 0x3c971814, 0x6b6a70a1, 0x687f3584, 0x52a0e286, 0xb79c5305, 0xaa500737,
|
||||
0x3e07841c, 0x7fdeae5c, 0x8e7d44ec, 0x5716f2b8, 0xb03ada37, 0xf0500c0d, 0xf01c1f04, 0x0200b3ff, 0xae0cf51a,
|
||||
0x3cb574b2, 0x25837a58, 0xdc0921bd, 0xd19113f9, 0x7ca92ff6, 0x94324773, 0x22f54701, 0x3ae5e581, 0x37c2dadc,
|
||||
0xc8b57634, 0x9af3dda7, 0xa9446146, 0x0fd0030e, 0xecc8c73e, 0xa4751e41, 0xe238cd99, 0x3bea0e2f, 0x3280bba1,
|
||||
0x183eb331, 0x4e548b38, 0x4f6db908, 0x6f420d03, 0xf60a04bf, 0x2cb81290, 0x24977c79, 0x5679b072, 0xbcaf89af,
|
||||
0xde9a771f, 0xd9930810, 0xb38bae12, 0xdccf3f2e, 0x5512721f, 0x2e6b7124, 0x501adde6, 0x9f84cd87, 0x7a584718,
|
||||
0x7408da17, 0xbc9f9abc, 0xe94b7d8c, 0xec7aec3a, 0xdb851dfa, 0x63094366, 0xc464c3d2, 0xef1c1847, 0x3215d908,
|
||||
0xdd433b37, 0x24c2ba16, 0x12a14d43, 0x2a65c451, 0x50940002, 0x133ae4dd, 0x71dff89e, 0x10314e55, 0x81ac77d6,
|
||||
0x5f11199b, 0x043556f1, 0xd7a3c76b, 0x3c11183b, 0x5924a509, 0xf28fe6ed, 0x97f1fbfa, 0x9ebabf2c, 0x1e153c6e,
|
||||
0x86e34570, 0xeae96fb1, 0x860e5e0a, 0x5a3e2ab3, 0x771fe71c, 0x4e3d06fa, 0x2965dcb9, 0x99e71d0f, 0x803e89d6,
|
||||
0x5266c825, 0x2e4cc978, 0x9c10b36a, 0xc6150eba, 0x94e2ea78, 0xa5fc3c53, 0x1e0a2df4, 0xf2f74ea7, 0x361d2b3d,
|
||||
0x1939260f, 0x19c27960, 0x5223a708, 0xf71312b6, 0xebadfe6e, 0xeac31f66, 0xe3bc4595, 0xa67bc883, 0xb17f37d1,
|
||||
0x018cff28, 0xc332ddef, 0xbe6c5aa5, 0x65582185, 0x68ab9802, 0xeecea50f, 0xdb2f953b, 0x2aef7dad, 0x5b6e2f84,
|
||||
0x1521b628, 0x29076170, 0xecdd4775, 0x619f1510, 0x13cca830, 0xeb61bd96, 0x0334fe1e, 0xaa0363cf, 0xb5735c90,
|
||||
0x4c70a239, 0xd59e9e0b, 0xcbaade14, 0xeecc86bc, 0x60622ca7, 0x9cab5cab, 0xb2f3846e, 0x648b1eaf, 0x19bdf0ca,
|
||||
0xa02369b9, 0x655abb50, 0x40685a32, 0x3c2ab4b3, 0x319ee9d5, 0xc021b8f7, 0x9b540b19, 0x875fa099, 0x95f7997e,
|
||||
0x623d7da8, 0xf837889a, 0x97e32d77, 0x11ed935f, 0x16681281, 0x0e358829, 0xc7e61fd6, 0x96dedfa1, 0x7858ba99,
|
||||
0x57f584a5, 0x1b227263, 0x9b83c3ff, 0x1ac24696, 0xcdb30aeb, 0x532e3054, 0x8fd948e4, 0x6dbc3128, 0x58ebf2ef,
|
||||
0x34c6ffea, 0xfe28ed61, 0xee7c3c73, 0x5d4a14d9, 0xe864b7e3, 0x42105d14, 0x203e13e0, 0x45eee2b6, 0xa3aaabea,
|
||||
0xdb6c4f15, 0xfacb4fd0, 0xc742f442, 0xef6abbb5, 0x654f3b1d, 0x41cd2105, 0xd81e799e, 0x86854dc7, 0xe44b476a,
|
||||
0x3d816250, 0xcf62a1f2, 0x5b8d2646, 0xfc8883a0, 0xc1c7b6a3, 0x7f1524c3, 0x69cb7492, 0x47848a0b, 0x5692b285,
|
||||
0x095bbf00, 0xad19489d, 0x1462b174, 0x23820e00, 0x58428d2a, 0x0c55f5ea, 0x1dadf43e, 0x233f7061, 0x3372f092,
|
||||
0x8d937e41, 0xd65fecf1, 0x6c223bdb, 0x7cde3759, 0xcbee7460, 0x4085f2a7, 0xce77326e, 0xa6078084, 0x19f8509e,
|
||||
0xe8efd855, 0x61d99735, 0xa969a7aa, 0xc50c06c2, 0x5a04abfc, 0x800bcadc, 0x9e447a2e, 0xc3453484, 0xfdd56705,
|
||||
0x0e1e9ec9, 0xdb73dbd3, 0x105588cd, 0x675fda79, 0xe3674340, 0xc5c43465, 0x713e38d8, 0x3d28f89e, 0xf16dff20,
|
||||
0x153e21e7, 0x8fb03d4a, 0xe6e39f2b, 0xdb83adf7
|
||||
],
|
||||
s2: [
|
||||
0xe93d5a68, 0x948140f7, 0xf64c261c, 0x94692934, 0x411520f7, 0x7602d4f7, 0xbcf46b2e, 0xd4a20068,
|
||||
0xd4082471, 0x3320f46a, 0x43b7d4b7, 0x500061af, 0x1e39f62e, 0x97244546, 0x14214f74, 0xbf8b8840,
|
||||
0x4d95fc1d, 0x96b591af, 0x70f4ddd3, 0x66a02f45, 0xbfbc09ec, 0x03bd9785, 0x7fac6dd0, 0x31cb8504,
|
||||
0x96eb27b3, 0x55fd3941, 0xda2547e6, 0xabca0a9a, 0x28507825, 0x530429f4, 0x0a2c86da, 0xe9b66dfb,
|
||||
0x68dc1462, 0xd7486900, 0x680ec0a4, 0x27a18dee, 0x4f3ffea2, 0xe887ad8c, 0xb58ce006, 0x7af4d6b6,
|
||||
0xaace1e7c, 0xd3375fec, 0xce78a399, 0x406b2a42, 0x20fe9e35, 0xd9f385b9, 0xee39d7ab, 0x3b124e8b,
|
||||
0x1dc9faf7, 0x4b6d1856, 0x26a36631, 0xeae397b2, 0x3a6efa74, 0xdd5b4332, 0x6841e7f7, 0xca7820fb,
|
||||
0xfb0af54e, 0xd8feb397, 0x454056ac, 0xba489527, 0x55533a3a, 0x20838d87, 0xfe6ba9b7, 0xd096954b,
|
||||
0x55a867bc, 0xa1159a58, 0xcca92963, 0x99e1db33, 0xa62a4a56, 0x3f3125f9, 0x5ef47e1c, 0x9029317c,
|
||||
0xfdf8e802, 0x04272f70, 0x80bb155c, 0x05282ce3, 0x95c11548, 0xe4c66d22, 0x48c1133f, 0xc70f86dc,
|
||||
0x07f9c9ee, 0x41041f0f, 0x404779a4, 0x5d886e17, 0x325f51eb, 0xd59bc0d1, 0xf2bcc18f, 0x41113564,
|
||||
0x257b7834, 0x602a9c60, 0xdff8e8a3, 0x1f636c1b, 0x0e12b4c2, 0x02e1329e, 0xaf664fd1, 0xcad18115,
|
||||
0x6b2395e0, 0x333e92e1, 0x3b240b62, 0xeebeb922, 0x85b2a20e, 0xe6ba0d99, 0xde720c8c, 0x2da2f728,
|
||||
0xd0127845, 0x95b794fd, 0x647d0862, 0xe7ccf5f0, 0x5449a36f, 0x877d48fa, 0xc39dfd27, 0xf33e8d1e,
|
||||
0x0a476341, 0x992eff74, 0x3a6f6eab, 0xf4f8fd37, 0xa812dc60, 0xa1ebddf8, 0x991be14c, 0xdb6e6b0d,
|
||||
0xc67b5510, 0x6d672c37, 0x2765d43b, 0xdcd0e804, 0xf1290dc7, 0xcc00ffa3, 0xb5390f92, 0x690fed0b,
|
||||
0x667b9ffb, 0xcedb7d9c, 0xa091cf0b, 0xd9155ea3, 0xbb132f88, 0x515bad24, 0x7b9479bf, 0x763bd6eb,
|
||||
0x37392eb3, 0xcc115979, 0x8026e297, 0xf42e312d, 0x6842ada7, 0xc66a2b3b, 0x12754ccc, 0x782ef11c,
|
||||
0x6a124237, 0xb79251e7, 0x06a1bbe6, 0x4bfb6350, 0x1a6b1018, 0x11caedfa, 0x3d25bdd8, 0xe2e1c3c9,
|
||||
0x44421659, 0x0a121386, 0xd90cec6e, 0xd5abea2a, 0x64af674e, 0xda86a85f, 0xbebfe988, 0x64e4c3fe,
|
||||
0x9dbc8057, 0xf0f7c086, 0x60787bf8, 0x6003604d, 0xd1fd8346, 0xf6381fb0, 0x7745ae04, 0xd736fccc,
|
||||
0x83426b33, 0xf01eab71, 0xb0804187, 0x3c005e5f, 0x77a057be, 0xbde8ae24, 0x55464299, 0xbf582e61,
|
||||
0x4e58f48f, 0xf2ddfda2, 0xf474ef38, 0x8789bdc2, 0x5366f9c3, 0xc8b38e74, 0xb475f255, 0x46fcd9b9,
|
||||
0x7aeb2661, 0x8b1ddf84, 0x846a0e79, 0x915f95e2, 0x466e598e, 0x20b45770, 0x8cd55591, 0xc902de4c,
|
||||
0xb90bace1, 0xbb8205d0, 0x11a86248, 0x7574a99e, 0xb77f19b6, 0xe0a9dc09, 0x662d09a1, 0xc4324633,
|
||||
0xe85a1f02, 0x09f0be8c, 0x4a99a025, 0x1d6efe10, 0x1ab93d1d, 0x0ba5a4df, 0xa186f20f, 0x2868f169,
|
||||
0xdcb7da83, 0x573906fe, 0xa1e2ce9b, 0x4fcd7f52, 0x50115e01, 0xa70683fa, 0xa002b5c4, 0x0de6d027,
|
||||
0x9af88c27, 0x773f8641, 0xc3604c06, 0x61a806b5, 0xf0177a28, 0xc0f586e0, 0x006058aa, 0x30dc7d62,
|
||||
0x11e69ed7, 0x2338ea63, 0x53c2dd94, 0xc2c21634, 0xbbcbee56, 0x90bcb6de, 0xebfc7da1, 0xce591d76,
|
||||
0x6f05e409, 0x4b7c0188, 0x39720a3d, 0x7c927c24, 0x86e3725f, 0x724d9db9, 0x1ac15bb4, 0xd39eb8fc,
|
||||
0xed545578, 0x08fca5b5, 0xd83d7cd3, 0x4dad0fc4, 0x1e50ef5e, 0xb161e6f8, 0xa28514d9, 0x6c51133c,
|
||||
0x6fd5c7e7, 0x56e14ec4, 0x362abfce, 0xddc6c837, 0xd79a3234, 0x92638212, 0x670efa8e, 0x406000e0
|
||||
0xe93d5a68, 0x948140f7, 0xf64c261c, 0x94692934, 0x411520f7, 0x7602d4f7, 0xbcf46b2e, 0xd4a20068, 0xd4082471,
|
||||
0x3320f46a, 0x43b7d4b7, 0x500061af, 0x1e39f62e, 0x97244546, 0x14214f74, 0xbf8b8840, 0x4d95fc1d, 0x96b591af,
|
||||
0x70f4ddd3, 0x66a02f45, 0xbfbc09ec, 0x03bd9785, 0x7fac6dd0, 0x31cb8504, 0x96eb27b3, 0x55fd3941, 0xda2547e6,
|
||||
0xabca0a9a, 0x28507825, 0x530429f4, 0x0a2c86da, 0xe9b66dfb, 0x68dc1462, 0xd7486900, 0x680ec0a4, 0x27a18dee,
|
||||
0x4f3ffea2, 0xe887ad8c, 0xb58ce006, 0x7af4d6b6, 0xaace1e7c, 0xd3375fec, 0xce78a399, 0x406b2a42, 0x20fe9e35,
|
||||
0xd9f385b9, 0xee39d7ab, 0x3b124e8b, 0x1dc9faf7, 0x4b6d1856, 0x26a36631, 0xeae397b2, 0x3a6efa74, 0xdd5b4332,
|
||||
0x6841e7f7, 0xca7820fb, 0xfb0af54e, 0xd8feb397, 0x454056ac, 0xba489527, 0x55533a3a, 0x20838d87, 0xfe6ba9b7,
|
||||
0xd096954b, 0x55a867bc, 0xa1159a58, 0xcca92963, 0x99e1db33, 0xa62a4a56, 0x3f3125f9, 0x5ef47e1c, 0x9029317c,
|
||||
0xfdf8e802, 0x04272f70, 0x80bb155c, 0x05282ce3, 0x95c11548, 0xe4c66d22, 0x48c1133f, 0xc70f86dc, 0x07f9c9ee,
|
||||
0x41041f0f, 0x404779a4, 0x5d886e17, 0x325f51eb, 0xd59bc0d1, 0xf2bcc18f, 0x41113564, 0x257b7834, 0x602a9c60,
|
||||
0xdff8e8a3, 0x1f636c1b, 0x0e12b4c2, 0x02e1329e, 0xaf664fd1, 0xcad18115, 0x6b2395e0, 0x333e92e1, 0x3b240b62,
|
||||
0xeebeb922, 0x85b2a20e, 0xe6ba0d99, 0xde720c8c, 0x2da2f728, 0xd0127845, 0x95b794fd, 0x647d0862, 0xe7ccf5f0,
|
||||
0x5449a36f, 0x877d48fa, 0xc39dfd27, 0xf33e8d1e, 0x0a476341, 0x992eff74, 0x3a6f6eab, 0xf4f8fd37, 0xa812dc60,
|
||||
0xa1ebddf8, 0x991be14c, 0xdb6e6b0d, 0xc67b5510, 0x6d672c37, 0x2765d43b, 0xdcd0e804, 0xf1290dc7, 0xcc00ffa3,
|
||||
0xb5390f92, 0x690fed0b, 0x667b9ffb, 0xcedb7d9c, 0xa091cf0b, 0xd9155ea3, 0xbb132f88, 0x515bad24, 0x7b9479bf,
|
||||
0x763bd6eb, 0x37392eb3, 0xcc115979, 0x8026e297, 0xf42e312d, 0x6842ada7, 0xc66a2b3b, 0x12754ccc, 0x782ef11c,
|
||||
0x6a124237, 0xb79251e7, 0x06a1bbe6, 0x4bfb6350, 0x1a6b1018, 0x11caedfa, 0x3d25bdd8, 0xe2e1c3c9, 0x44421659,
|
||||
0x0a121386, 0xd90cec6e, 0xd5abea2a, 0x64af674e, 0xda86a85f, 0xbebfe988, 0x64e4c3fe, 0x9dbc8057, 0xf0f7c086,
|
||||
0x60787bf8, 0x6003604d, 0xd1fd8346, 0xf6381fb0, 0x7745ae04, 0xd736fccc, 0x83426b33, 0xf01eab71, 0xb0804187,
|
||||
0x3c005e5f, 0x77a057be, 0xbde8ae24, 0x55464299, 0xbf582e61, 0x4e58f48f, 0xf2ddfda2, 0xf474ef38, 0x8789bdc2,
|
||||
0x5366f9c3, 0xc8b38e74, 0xb475f255, 0x46fcd9b9, 0x7aeb2661, 0x8b1ddf84, 0x846a0e79, 0x915f95e2, 0x466e598e,
|
||||
0x20b45770, 0x8cd55591, 0xc902de4c, 0xb90bace1, 0xbb8205d0, 0x11a86248, 0x7574a99e, 0xb77f19b6, 0xe0a9dc09,
|
||||
0x662d09a1, 0xc4324633, 0xe85a1f02, 0x09f0be8c, 0x4a99a025, 0x1d6efe10, 0x1ab93d1d, 0x0ba5a4df, 0xa186f20f,
|
||||
0x2868f169, 0xdcb7da83, 0x573906fe, 0xa1e2ce9b, 0x4fcd7f52, 0x50115e01, 0xa70683fa, 0xa002b5c4, 0x0de6d027,
|
||||
0x9af88c27, 0x773f8641, 0xc3604c06, 0x61a806b5, 0xf0177a28, 0xc0f586e0, 0x006058aa, 0x30dc7d62, 0x11e69ed7,
|
||||
0x2338ea63, 0x53c2dd94, 0xc2c21634, 0xbbcbee56, 0x90bcb6de, 0xebfc7da1, 0xce591d76, 0x6f05e409, 0x4b7c0188,
|
||||
0x39720a3d, 0x7c927c24, 0x86e3725f, 0x724d9db9, 0x1ac15bb4, 0xd39eb8fc, 0xed545578, 0x08fca5b5, 0xd83d7cd3,
|
||||
0x4dad0fc4, 0x1e50ef5e, 0xb161e6f8, 0xa28514d9, 0x6c51133c, 0x6fd5c7e7, 0x56e14ec4, 0x362abfce, 0xddc6c837,
|
||||
0xd79a3234, 0x92638212, 0x670efa8e, 0x406000e0
|
||||
],
|
||||
s3: [
|
||||
0x3a39ce37, 0xd3faf5cf, 0xabc27737, 0x5ac52d1b, 0x5cb0679e, 0x4fa33742, 0xd3822740, 0x99bc9bbe,
|
||||
0xd5118e9d, 0xbf0f7315, 0xd62d1c7e, 0xc700c47b, 0xb78c1b6b, 0x21a19045, 0xb26eb1be, 0x6a366eb4,
|
||||
0x5748ab2f, 0xbc946e79, 0xc6a376d2, 0x6549c2c8, 0x530ff8ee, 0x468dde7d, 0xd5730a1d, 0x4cd04dc6,
|
||||
0x2939bbdb, 0xa9ba4650, 0xac9526e8, 0xbe5ee304, 0xa1fad5f0, 0x6a2d519a, 0x63ef8ce2, 0x9a86ee22,
|
||||
0xc089c2b8, 0x43242ef6, 0xa51e03aa, 0x9cf2d0a4, 0x83c061ba, 0x9be96a4d, 0x8fe51550, 0xba645bd6,
|
||||
0x2826a2f9, 0xa73a3ae1, 0x4ba99586, 0xef5562e9, 0xc72fefd3, 0xf752f7da, 0x3f046f69, 0x77fa0a59,
|
||||
0x80e4a915, 0x87b08601, 0x9b09e6ad, 0x3b3ee593, 0xe990fd5a, 0x9e34d797, 0x2cf0b7d9, 0x022b8b51,
|
||||
0x96d5ac3a, 0x017da67d, 0xd1cf3ed6, 0x7c7d2d28, 0x1f9f25cf, 0xadf2b89b, 0x5ad6b472, 0x5a88f54c,
|
||||
0xe029ac71, 0xe019a5e6, 0x47b0acfd, 0xed93fa9b, 0xe8d3c48d, 0x283b57cc, 0xf8d56629, 0x79132e28,
|
||||
0x785f0191, 0xed756055, 0xf7960e44, 0xe3d35e8c, 0x15056dd4, 0x88f46dba, 0x03a16125, 0x0564f0bd,
|
||||
0xc3eb9e15, 0x3c9057a2, 0x97271aec, 0xa93a072a, 0x1b3f6d9b, 0x1e6321f5, 0xf59c66fb, 0x26dcf319,
|
||||
0x7533d928, 0xb155fdf5, 0x03563482, 0x8aba3cbb, 0x28517711, 0xc20ad9f8, 0xabcc5167, 0xccad925f,
|
||||
0x4de81751, 0x3830dc8e, 0x379d5862, 0x9320f991, 0xea7a90c2, 0xfb3e7bce, 0x5121ce64, 0x774fbe32,
|
||||
0xa8b6e37e, 0xc3293d46, 0x48de5369, 0x6413e680, 0xa2ae0810, 0xdd6db224, 0x69852dfd, 0x09072166,
|
||||
0xb39a460a, 0x6445c0dd, 0x586cdecf, 0x1c20c8ae, 0x5bbef7dd, 0x1b588d40, 0xccd2017f, 0x6bb4e3bb,
|
||||
0xdda26a7e, 0x3a59ff45, 0x3e350a44, 0xbcb4cdd5, 0x72eacea8, 0xfa6484bb, 0x8d6612ae, 0xbf3c6f47,
|
||||
0xd29be463, 0x542f5d9e, 0xaec2771b, 0xf64e6370, 0x740e0d8d, 0xe75b1357, 0xf8721671, 0xaf537d5d,
|
||||
0x4040cb08, 0x4eb4e2cc, 0x34d2466a, 0x0115af84, 0xe1b00428, 0x95983a1d, 0x06b89fb4, 0xce6ea048,
|
||||
0x6f3f3b82, 0x3520ab82, 0x011a1d4b, 0x277227f8, 0x611560b1, 0xe7933fdc, 0xbb3a792b, 0x344525bd,
|
||||
0xa08839e1, 0x51ce794b, 0x2f32c9b7, 0xa01fbac9, 0xe01cc87e, 0xbcc7d1f6, 0xcf0111c3, 0xa1e8aac7,
|
||||
0x1a908749, 0xd44fbd9a, 0xd0dadecb, 0xd50ada38, 0x0339c32a, 0xc6913667, 0x8df9317c, 0xe0b12b4f,
|
||||
0xf79e59b7, 0x43f5bb3a, 0xf2d519ff, 0x27d9459c, 0xbf97222c, 0x15e6fc2a, 0x0f91fc71, 0x9b941525,
|
||||
0xfae59361, 0xceb69ceb, 0xc2a86459, 0x12baa8d1, 0xb6c1075e, 0xe3056a0c, 0x10d25065, 0xcb03a442,
|
||||
0xe0ec6e0e, 0x1698db3b, 0x4c98a0be, 0x3278e964, 0x9f1f9532, 0xe0d392df, 0xd3a0342b, 0x8971f21e,
|
||||
0x1b0a7441, 0x4ba3348c, 0xc5be7120, 0xc37632d8, 0xdf359f8d, 0x9b992f2e, 0xe60b6f47, 0x0fe3f11d,
|
||||
0xe54cda54, 0x1edad891, 0xce6279cf, 0xcd3e7e6f, 0x1618b166, 0xfd2c1d05, 0x848fd2c5, 0xf6fb2299,
|
||||
0xf523f357, 0xa6327623, 0x93a83531, 0x56cccd02, 0xacf08162, 0x5a75ebb5, 0x6e163697, 0x88d273cc,
|
||||
0xde966292, 0x81b949d0, 0x4c50901b, 0x71c65614, 0xe6c6c7bd, 0x327a140a, 0x45e1d006, 0xc3f27b9a,
|
||||
0xc9aa53fd, 0x62a80f00, 0xbb25bfe2, 0x35bdd2f6, 0x71126905, 0xb2040222, 0xb6cbcf7c, 0xcd769c2b,
|
||||
0x53113ec0, 0x1640e3d3, 0x38abbd60, 0x2547adf0, 0xba38209c, 0xf746ce76, 0x77afa1c5, 0x20756060,
|
||||
0x85cbfe4e, 0x8ae88dd8, 0x7aaaf9b0, 0x4cf9aa7e, 0x1948c25c, 0x02fb8a8c, 0x01c36ae4, 0xd6ebe1f9,
|
||||
0x90d4f869, 0xa65cdea0, 0x3f09252d, 0xc208e69f, 0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6
|
||||
0x3a39ce37, 0xd3faf5cf, 0xabc27737, 0x5ac52d1b, 0x5cb0679e, 0x4fa33742, 0xd3822740, 0x99bc9bbe, 0xd5118e9d,
|
||||
0xbf0f7315, 0xd62d1c7e, 0xc700c47b, 0xb78c1b6b, 0x21a19045, 0xb26eb1be, 0x6a366eb4, 0x5748ab2f, 0xbc946e79,
|
||||
0xc6a376d2, 0x6549c2c8, 0x530ff8ee, 0x468dde7d, 0xd5730a1d, 0x4cd04dc6, 0x2939bbdb, 0xa9ba4650, 0xac9526e8,
|
||||
0xbe5ee304, 0xa1fad5f0, 0x6a2d519a, 0x63ef8ce2, 0x9a86ee22, 0xc089c2b8, 0x43242ef6, 0xa51e03aa, 0x9cf2d0a4,
|
||||
0x83c061ba, 0x9be96a4d, 0x8fe51550, 0xba645bd6, 0x2826a2f9, 0xa73a3ae1, 0x4ba99586, 0xef5562e9, 0xc72fefd3,
|
||||
0xf752f7da, 0x3f046f69, 0x77fa0a59, 0x80e4a915, 0x87b08601, 0x9b09e6ad, 0x3b3ee593, 0xe990fd5a, 0x9e34d797,
|
||||
0x2cf0b7d9, 0x022b8b51, 0x96d5ac3a, 0x017da67d, 0xd1cf3ed6, 0x7c7d2d28, 0x1f9f25cf, 0xadf2b89b, 0x5ad6b472,
|
||||
0x5a88f54c, 0xe029ac71, 0xe019a5e6, 0x47b0acfd, 0xed93fa9b, 0xe8d3c48d, 0x283b57cc, 0xf8d56629, 0x79132e28,
|
||||
0x785f0191, 0xed756055, 0xf7960e44, 0xe3d35e8c, 0x15056dd4, 0x88f46dba, 0x03a16125, 0x0564f0bd, 0xc3eb9e15,
|
||||
0x3c9057a2, 0x97271aec, 0xa93a072a, 0x1b3f6d9b, 0x1e6321f5, 0xf59c66fb, 0x26dcf319, 0x7533d928, 0xb155fdf5,
|
||||
0x03563482, 0x8aba3cbb, 0x28517711, 0xc20ad9f8, 0xabcc5167, 0xccad925f, 0x4de81751, 0x3830dc8e, 0x379d5862,
|
||||
0x9320f991, 0xea7a90c2, 0xfb3e7bce, 0x5121ce64, 0x774fbe32, 0xa8b6e37e, 0xc3293d46, 0x48de5369, 0x6413e680,
|
||||
0xa2ae0810, 0xdd6db224, 0x69852dfd, 0x09072166, 0xb39a460a, 0x6445c0dd, 0x586cdecf, 0x1c20c8ae, 0x5bbef7dd,
|
||||
0x1b588d40, 0xccd2017f, 0x6bb4e3bb, 0xdda26a7e, 0x3a59ff45, 0x3e350a44, 0xbcb4cdd5, 0x72eacea8, 0xfa6484bb,
|
||||
0x8d6612ae, 0xbf3c6f47, 0xd29be463, 0x542f5d9e, 0xaec2771b, 0xf64e6370, 0x740e0d8d, 0xe75b1357, 0xf8721671,
|
||||
0xaf537d5d, 0x4040cb08, 0x4eb4e2cc, 0x34d2466a, 0x0115af84, 0xe1b00428, 0x95983a1d, 0x06b89fb4, 0xce6ea048,
|
||||
0x6f3f3b82, 0x3520ab82, 0x011a1d4b, 0x277227f8, 0x611560b1, 0xe7933fdc, 0xbb3a792b, 0x344525bd, 0xa08839e1,
|
||||
0x51ce794b, 0x2f32c9b7, 0xa01fbac9, 0xe01cc87e, 0xbcc7d1f6, 0xcf0111c3, 0xa1e8aac7, 0x1a908749, 0xd44fbd9a,
|
||||
0xd0dadecb, 0xd50ada38, 0x0339c32a, 0xc6913667, 0x8df9317c, 0xe0b12b4f, 0xf79e59b7, 0x43f5bb3a, 0xf2d519ff,
|
||||
0x27d9459c, 0xbf97222c, 0x15e6fc2a, 0x0f91fc71, 0x9b941525, 0xfae59361, 0xceb69ceb, 0xc2a86459, 0x12baa8d1,
|
||||
0xb6c1075e, 0xe3056a0c, 0x10d25065, 0xcb03a442, 0xe0ec6e0e, 0x1698db3b, 0x4c98a0be, 0x3278e964, 0x9f1f9532,
|
||||
0xe0d392df, 0xd3a0342b, 0x8971f21e, 0x1b0a7441, 0x4ba3348c, 0xc5be7120, 0xc37632d8, 0xdf359f8d, 0x9b992f2e,
|
||||
0xe60b6f47, 0x0fe3f11d, 0xe54cda54, 0x1edad891, 0xce6279cf, 0xcd3e7e6f, 0x1618b166, 0xfd2c1d05, 0x848fd2c5,
|
||||
0xf6fb2299, 0xf523f357, 0xa6327623, 0x93a83531, 0x56cccd02, 0xacf08162, 0x5a75ebb5, 0x6e163697, 0x88d273cc,
|
||||
0xde966292, 0x81b949d0, 0x4c50901b, 0x71c65614, 0xe6c6c7bd, 0x327a140a, 0x45e1d006, 0xc3f27b9a, 0xc9aa53fd,
|
||||
0x62a80f00, 0xbb25bfe2, 0x35bdd2f6, 0x71126905, 0xb2040222, 0xb6cbcf7c, 0xcd769c2b, 0x53113ec0, 0x1640e3d3,
|
||||
0x38abbd60, 0x2547adf0, 0xba38209c, 0xf746ce76, 0x77afa1c5, 0x20756060, 0x85cbfe4e, 0x8ae88dd8, 0x7aaaf9b0,
|
||||
0x4cf9aa7e, 0x1948c25c, 0x02fb8a8c, 0x01c36ae4, 0xd6ebe1f9, 0x90d4f869, 0xa65cdea0, 0x3f09252d, 0xc208e69f,
|
||||
0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6
|
||||
]
|
||||
};
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// fixes based on patch submitted by Peter Wood (#5791)
|
||||
const xor = function(x, y) {
|
||||
return (((x>>0x10)^(y>>0x10))<<0x10)|(((x&0xffff)^(y&0xffff))&0xffff);
|
||||
const xor = function (x, y) {
|
||||
return (((x >> 0x10) ^ (y >> 0x10)) << 0x10) | (((x & 0xffff) ^ (y & 0xffff)) & 0xffff);
|
||||
};
|
||||
|
||||
const f = function (v, box) {
|
||||
const d = box.s3[v & 0xff];
|
||||
v >>= 8;
|
||||
const c = box.s2[v & 0xff];
|
||||
v >>= 8;
|
||||
const b = box.s1[v & 0xff];
|
||||
v >>= 8;
|
||||
const a = box.s0[v & 0xff];
|
||||
|
||||
const f = function(v, box) {
|
||||
const d=box.s3[v&0xff]; v>>=8;
|
||||
const c=box.s2[v&0xff]; v>>=8;
|
||||
const b=box.s1[v&0xff]; v>>=8;
|
||||
const a=box.s0[v&0xff];
|
||||
|
||||
let r = (((a>>0x10)+(b>>0x10)+(((a&0xffff)+(b&0xffff))>>0x10))<<0x10)|(((a&0xffff)+(b&0xffff))&0xffff);
|
||||
r = (((r>>0x10)^(c>>0x10))<<0x10)|(((r&0xffff)^(c&0xffff))&0xffff);
|
||||
return (((r>>0x10)+(d>>0x10)+(((r&0xffff)+(d&0xffff))>>0x10))<<0x10)|(((r&0xffff)+(d&0xffff))&0xffff);
|
||||
let r
|
||||
= (((a >> 0x10) + (b >> 0x10) + (((a & 0xffff) + (b & 0xffff)) >> 0x10)) << 0x10)
|
||||
| (((a & 0xffff) + (b & 0xffff)) & 0xffff);
|
||||
r = (((r >> 0x10) ^ (c >> 0x10)) << 0x10) | (((r & 0xffff) ^ (c & 0xffff)) & 0xffff);
|
||||
return (
|
||||
(((r >> 0x10) + (d >> 0x10) + (((r & 0xffff) + (d & 0xffff)) >> 0x10)) << 0x10)
|
||||
| (((r & 0xffff) + (d & 0xffff)) & 0xffff)
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
const eb = function(o, box) {
|
||||
// TODO: see if this can't be made more efficient
|
||||
let l=o.left;
|
||||
let r=o.right;
|
||||
l=xor(l, box.p[0]);
|
||||
r=xor(r, xor(f(l, box), box.p[1]));
|
||||
l=xor(l, xor(f(r, box), box.p[2]));
|
||||
r=xor(r, xor(f(l, box), box.p[3]));
|
||||
l=xor(l, xor(f(r, box), box.p[4]));
|
||||
r=xor(r, xor(f(l, box), box.p[5]));
|
||||
l=xor(l, xor(f(r, box), box.p[6]));
|
||||
r=xor(r, xor(f(l, box), box.p[7]));
|
||||
l=xor(l, xor(f(r, box), box.p[8]));
|
||||
r=xor(r, xor(f(l, box), box.p[9]));
|
||||
l=xor(l, xor(f(r, box), box.p[10]));
|
||||
r=xor(r, xor(f(l, box), box.p[11]));
|
||||
l=xor(l, xor(f(r, box), box.p[12]));
|
||||
r=xor(r, xor(f(l, box), box.p[13]));
|
||||
l=xor(l, xor(f(r, box), box.p[14]));
|
||||
r=xor(r, xor(f(l, box), box.p[15]));
|
||||
l=xor(l, xor(f(r, box), box.p[16]));
|
||||
o.right=l;
|
||||
o.left=xor(r, box.p[17]);
|
||||
const eb = function (o, box) {
|
||||
// TODO: see if this can't be made more efficient
|
||||
let l = o.left;
|
||||
let r = o.right;
|
||||
l = xor(l, box.p[0]);
|
||||
r = xor(r, xor(f(l, box), box.p[1]));
|
||||
l = xor(l, xor(f(r, box), box.p[2]));
|
||||
r = xor(r, xor(f(l, box), box.p[3]));
|
||||
l = xor(l, xor(f(r, box), box.p[4]));
|
||||
r = xor(r, xor(f(l, box), box.p[5]));
|
||||
l = xor(l, xor(f(r, box), box.p[6]));
|
||||
r = xor(r, xor(f(l, box), box.p[7]));
|
||||
l = xor(l, xor(f(r, box), box.p[8]));
|
||||
r = xor(r, xor(f(l, box), box.p[9]));
|
||||
l = xor(l, xor(f(r, box), box.p[10]));
|
||||
r = xor(r, xor(f(l, box), box.p[11]));
|
||||
l = xor(l, xor(f(r, box), box.p[12]));
|
||||
r = xor(r, xor(f(l, box), box.p[13]));
|
||||
l = xor(l, xor(f(r, box), box.p[14]));
|
||||
r = xor(r, xor(f(l, box), box.p[15]));
|
||||
l = xor(l, xor(f(r, box), box.p[16]));
|
||||
o.right = l;
|
||||
o.left = xor(r, box.p[17]);
|
||||
};
|
||||
|
||||
const db = function(o, box) {
|
||||
let l=o.left;
|
||||
let r=o.right;
|
||||
l=xor(l, box.p[17]);
|
||||
r=xor(r, xor(f(l, box), box.p[16]));
|
||||
l=xor(l, xor(f(r, box), box.p[15]));
|
||||
r=xor(r, xor(f(l, box), box.p[14]));
|
||||
l=xor(l, xor(f(r, box), box.p[13]));
|
||||
r=xor(r, xor(f(l, box), box.p[12]));
|
||||
l=xor(l, xor(f(r, box), box.p[11]));
|
||||
r=xor(r, xor(f(l, box), box.p[10]));
|
||||
l=xor(l, xor(f(r, box), box.p[9]));
|
||||
r=xor(r, xor(f(l, box), box.p[8]));
|
||||
l=xor(l, xor(f(r, box), box.p[7]));
|
||||
r=xor(r, xor(f(l, box), box.p[6]));
|
||||
l=xor(l, xor(f(r, box), box.p[5]));
|
||||
r=xor(r, xor(f(l, box), box.p[4]));
|
||||
l=xor(l, xor(f(r, box), box.p[3]));
|
||||
r=xor(r, xor(f(l, box), box.p[2]));
|
||||
l=xor(l, xor(f(r, box), box.p[1]));
|
||||
o.right=l;
|
||||
o.left=xor(r, box.p[0]);
|
||||
const db = function (o, box) {
|
||||
let l = o.left;
|
||||
let r = o.right;
|
||||
l = xor(l, box.p[17]);
|
||||
r = xor(r, xor(f(l, box), box.p[16]));
|
||||
l = xor(l, xor(f(r, box), box.p[15]));
|
||||
r = xor(r, xor(f(l, box), box.p[14]));
|
||||
l = xor(l, xor(f(r, box), box.p[13]));
|
||||
r = xor(r, xor(f(l, box), box.p[12]));
|
||||
l = xor(l, xor(f(r, box), box.p[11]));
|
||||
r = xor(r, xor(f(l, box), box.p[10]));
|
||||
l = xor(l, xor(f(r, box), box.p[9]));
|
||||
r = xor(r, xor(f(l, box), box.p[8]));
|
||||
l = xor(l, xor(f(r, box), box.p[7]));
|
||||
r = xor(r, xor(f(l, box), box.p[6]));
|
||||
l = xor(l, xor(f(r, box), box.p[5]));
|
||||
r = xor(r, xor(f(l, box), box.p[4]));
|
||||
l = xor(l, xor(f(r, box), box.p[3]));
|
||||
r = xor(r, xor(f(l, box), box.p[2]));
|
||||
l = xor(l, xor(f(r, box), box.p[1]));
|
||||
o.right = l;
|
||||
o.left = xor(r, box.p[0]);
|
||||
};
|
||||
|
||||
const encryptBlock=function(inblock, outblock, box) {
|
||||
const encryptBlock = function (inblock, outblock, box) {
|
||||
const o = {};
|
||||
o.left=inblock[0];
|
||||
o.right=inblock[1];
|
||||
o.left = inblock[0];
|
||||
o.right = inblock[1];
|
||||
eb(o, box);
|
||||
outblock[0] = o.left;
|
||||
outblock[1] = o.right;
|
||||
};
|
||||
|
||||
const decryptBlock=function(inblock, outblock, box) {
|
||||
const o= {};
|
||||
o.left=inblock[0];
|
||||
o.right=inblock[1];
|
||||
const decryptBlock = function (inblock, outblock, box) {
|
||||
const o = {};
|
||||
o.left = inblock[0];
|
||||
o.right = inblock[1];
|
||||
db(o, box);
|
||||
outblock[0] = o.left;
|
||||
outblock[1] = o.right;
|
||||
};
|
||||
|
||||
crypto.Blowfish = new function() {
|
||||
this.createCipher=function(key, modeName) {
|
||||
crypto.Blowfish = new (function () {
|
||||
this.createCipher = function (key, modeName) {
|
||||
return new forge.cipher.BlockCipher({
|
||||
algorithm: new Blowfish.Algorithm(key, modeName),
|
||||
key: key,
|
||||
|
@ -342,74 +333,73 @@ crypto.Blowfish = new function() {
|
|||
});
|
||||
};
|
||||
|
||||
this.createDecipher=function(key, modeName) {
|
||||
this.createDecipher = function (key, modeName) {
|
||||
return new forge.cipher.BlockCipher({
|
||||
algorithm: new Blowfish.Algorithm(key, modeName),
|
||||
key: key,
|
||||
decrypt: true
|
||||
});
|
||||
};
|
||||
}();
|
||||
})();
|
||||
|
||||
|
||||
crypto.Blowfish.Algorithm=function(key, modeName) {
|
||||
this.initialize({key: key});
|
||||
crypto.Blowfish.Algorithm = function (key, modeName) {
|
||||
this.initialize({ key: key });
|
||||
const _box = this.box;
|
||||
const modeOption = {
|
||||
blockSize: 8,
|
||||
cipher: {
|
||||
encrypt: function(inblock, outblock) {
|
||||
encrypt: function (inblock, outblock) {
|
||||
encryptBlock(inblock, outblock, _box);
|
||||
},
|
||||
decrypt: function(inblock, outblock) {
|
||||
decrypt: function (inblock, outblock) {
|
||||
decryptBlock(inblock, outblock, _box);
|
||||
},
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
switch (modeName.toLowerCase()) {
|
||||
case "ecb":
|
||||
this.mode=new forge.cipher.modes.ecb(modeOption);
|
||||
this.mode = new forge.cipher.modes.ecb(modeOption);
|
||||
break;
|
||||
case "cbc":
|
||||
this.mode=new forge.cipher.modes.cbc(modeOption);
|
||||
this.mode = new forge.cipher.modes.cbc(modeOption);
|
||||
break;
|
||||
case "cfb":
|
||||
this.mode=new forge.cipher.modes.cfb(modeOption);
|
||||
this.mode = new forge.cipher.modes.cfb(modeOption);
|
||||
break;
|
||||
case "ofb":
|
||||
this.mode=new forge.cipher.modes.ofb(modeOption);
|
||||
this.mode = new forge.cipher.modes.ofb(modeOption);
|
||||
break;
|
||||
case "ctr":
|
||||
this.mode=new forge.cipher.modes.ctr(modeOption);
|
||||
this.mode = new forge.cipher.modes.ctr(modeOption);
|
||||
break;
|
||||
default:
|
||||
this.mode=new forge.cipher.modes.ecb(modeOption);
|
||||
this.mode = new forge.cipher.modes.ecb(modeOption);
|
||||
break;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
crypto.Blowfish.Algorithm.prototype.initialize=function(options) {
|
||||
const POW8=Math.pow(2, 8);
|
||||
crypto.Blowfish.Algorithm.prototype.initialize = function (options) {
|
||||
const POW8 = Math.pow(2, 8);
|
||||
|
||||
let k=options.key;
|
||||
let k = options.key;
|
||||
if (lang.isString(k)) {
|
||||
k = arrayUtil.map(k.split(""), function(item) {
|
||||
k = arrayUtil.map(k.split(""), function (item) {
|
||||
return item.charCodeAt(0) & 0xff;
|
||||
});
|
||||
}
|
||||
|
||||
// init the boxes
|
||||
let pos=0, data=0;
|
||||
const res={ left: 0, right: 0 };
|
||||
// init the boxes
|
||||
let pos = 0,
|
||||
data = 0;
|
||||
const res = { left: 0, right: 0 };
|
||||
const box = {
|
||||
p: arrayUtil.map(boxes.p.slice(0), function(item) {
|
||||
const l=k.length;
|
||||
for (let j=0; j<4; j++) {
|
||||
data=(data*POW8)|k[pos++ % l];
|
||||
p: arrayUtil.map(boxes.p.slice(0), function (item) {
|
||||
const l = k.length;
|
||||
for (let j = 0; j < 4; j++) {
|
||||
data = (data * POW8) | k[pos++ % l];
|
||||
}
|
||||
return (((item>>0x10)^(data>>0x10))<<0x10)|(((item&0xffff)^(data&0xffff))&0xffff);
|
||||
return (((item >> 0x10) ^ (data >> 0x10)) << 0x10) | (((item & 0xffff) ^ (data & 0xffff)) & 0xffff);
|
||||
}),
|
||||
s0: boxes.s0.slice(0),
|
||||
s1: boxes.s1.slice(0),
|
||||
|
@ -417,17 +407,17 @@ crypto.Blowfish.Algorithm.prototype.initialize=function(options) {
|
|||
s3: boxes.s3.slice(0)
|
||||
};
|
||||
|
||||
// encrypt p and the s boxes
|
||||
for (let i=0, l=box.p.length; i<l;) {
|
||||
// encrypt p and the s boxes
|
||||
for (let i = 0, l = box.p.length; i < l;) {
|
||||
eb(res, box);
|
||||
box.p[i++]=res.left;
|
||||
box.p[i++]=res.right;
|
||||
box.p[i++] = res.left;
|
||||
box.p[i++] = res.right;
|
||||
}
|
||||
for (let i=0; i<4; i++) {
|
||||
for (let j=0, l=box["s"+i].length; j<l;) {
|
||||
for (let i = 0; i < 4; i++) {
|
||||
for (let j = 0, l = box["s" + i].length; j < l;) {
|
||||
eb(res, box);
|
||||
box["s"+i][j++]=res.left;
|
||||
box["s"+i][j++]=res.right;
|
||||
box["s" + i][j++] = res.left;
|
||||
box["s" + i][j++] = res.right;
|
||||
}
|
||||
}
|
||||
this.box = box;
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
|
||||
import OperationError from "../errors/OperationError.mjs";
|
||||
import Utils from "../Utils.mjs";
|
||||
import {Rotor, Plugboard, a2i, i2a} from "./Enigma.mjs";
|
||||
import { Rotor, Plugboard, a2i, i2a } from "./Enigma.mjs";
|
||||
|
||||
/**
|
||||
* Convenience/optimisation subclass of Rotor
|
||||
|
@ -29,7 +29,7 @@ class CopyRotor extends Rotor {
|
|||
pos: this.pos,
|
||||
step: this.step,
|
||||
transform: this.transform,
|
||||
revTransform: this.revTransform,
|
||||
revTransform: this.revTransform
|
||||
};
|
||||
return clone;
|
||||
}
|
||||
|
@ -96,7 +96,7 @@ class SharedScrambler {
|
|||
constructor(rotors, reflector) {
|
||||
this.lowerCache = new Array(26);
|
||||
this.higherCache = new Array(26);
|
||||
for (let i=0; i<26; i++) {
|
||||
for (let i = 0; i < 26; i++) {
|
||||
this.higherCache[i] = new Array(26);
|
||||
}
|
||||
this.changeRotors(rotors, reflector);
|
||||
|
@ -121,7 +121,7 @@ class SharedScrambler {
|
|||
* the shared state, so should be 2 or more.
|
||||
*/
|
||||
step(n) {
|
||||
for (let i=0; i<n-1; i++) {
|
||||
for (let i = 0; i < n - 1; i++) {
|
||||
this.rotors[i].step();
|
||||
}
|
||||
this.cacheGen();
|
||||
|
@ -136,13 +136,13 @@ class SharedScrambler {
|
|||
* iterations.
|
||||
*/
|
||||
cacheGen() {
|
||||
for (let i=0; i<26; i++) {
|
||||
for (let i = 0; i < 26; i++) {
|
||||
this.lowerCache[i] = undefined;
|
||||
for (let j=0; j<26; j++) {
|
||||
for (let j = 0; j < 26; j++) {
|
||||
this.higherCache[i][j] = undefined;
|
||||
}
|
||||
}
|
||||
for (let i=0; i<26; i++) {
|
||||
for (let i = 0; i < 26; i++) {
|
||||
if (this.lowerCache[i] !== undefined) {
|
||||
continue;
|
||||
}
|
||||
|
@ -219,7 +219,6 @@ class Scrambler {
|
|||
this.cache = this.baseScrambler.higherCache[this.rotor.pos];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Run a letter through the scrambler.
|
||||
* @param {number} i - The letter to transform (as a number)
|
||||
|
@ -262,7 +261,7 @@ class Scrambler {
|
|||
// Roll back the fast rotor by one step
|
||||
let pos = Utils.mod(this.rotor.pos - 1, 26);
|
||||
result += i2a(pos);
|
||||
for (let i=0; i<this.baseScrambler.rotors.length; i++) {
|
||||
for (let i = 0; i < this.baseScrambler.rotors.length; i++) {
|
||||
pos = this.baseScrambler.rotors[i].pos;
|
||||
result += i2a(pos);
|
||||
}
|
||||
|
@ -296,7 +295,7 @@ export class BombeMachine {
|
|||
* @param {boolean} check - Whether to use the checking machine
|
||||
* @param {function} update - Function to call to send status updates (optional)
|
||||
*/
|
||||
constructor(rotors, reflector, ciphertext, crib, check, update=undefined) {
|
||||
constructor(rotors, reflector, ciphertext, crib, check, update = undefined) {
|
||||
if (ciphertext.length < crib.length) {
|
||||
throw new OperationError("Crib overruns supplied ciphertext");
|
||||
}
|
||||
|
@ -310,9 +309,11 @@ export class BombeMachine {
|
|||
// A shorter crib is preferable to reduce this chance, of course
|
||||
throw new OperationError("Crib is too long");
|
||||
}
|
||||
for (let i=0; i<crib.length; i++) {
|
||||
for (let i = 0; i < crib.length; i++) {
|
||||
if (ciphertext[i] === crib[i]) {
|
||||
throw new OperationError(`Invalid crib: character ${ciphertext[i]} at pos ${i} in both ciphertext and crib`);
|
||||
throw new OperationError(
|
||||
`Invalid crib: character ${ciphertext[i]} at pos ${i} in both ciphertext and crib`
|
||||
);
|
||||
}
|
||||
}
|
||||
this.ciphertext = ciphertext;
|
||||
|
@ -325,12 +326,12 @@ export class BombeMachine {
|
|||
|
||||
// This is the bundle of wires corresponding to the 26 letters within each of the 26
|
||||
// possible nodes in the menu
|
||||
this.wires = new Array(26*26);
|
||||
this.wires = new Array(26 * 26);
|
||||
|
||||
// These are the pseudo-Engima devices corresponding to each edge in the menu, and the
|
||||
// nodes in the menu they each connect to
|
||||
this.scramblers = new Array();
|
||||
for (let i=0; i<26; i++) {
|
||||
for (let i = 0; i < 26; i++) {
|
||||
this.scramblers.push(new Array());
|
||||
}
|
||||
this.sharedScrambler = new SharedScrambler(this.baseRotors.slice(1), reflector);
|
||||
|
@ -465,7 +466,7 @@ export class BombeMachine {
|
|||
}
|
||||
}
|
||||
// Then all edges
|
||||
for (let i=0; i<this.crib.length; i++) {
|
||||
for (let i = 0; i < this.crib.length; i++) {
|
||||
const a = this.crib[i];
|
||||
const b = this.ciphertext[i];
|
||||
new Edge(i, nodes.get(a), nodes.get(b));
|
||||
|
@ -499,14 +500,14 @@ export class BombeMachine {
|
|||
* @param {number} j - Bombe stecker hypothesis wire within bundle
|
||||
*/
|
||||
energise(i, j) {
|
||||
const idx = 26*i + j;
|
||||
const idx = 26 * i + j;
|
||||
if (this.wires[idx]) {
|
||||
return;
|
||||
}
|
||||
this.wires[idx] = true;
|
||||
// Welchman's diagonal board: if A steckers to B, that implies B steckers to A. Handle
|
||||
// both.
|
||||
const idxPair = 26*j + i;
|
||||
const idxPair = 26 * j + i;
|
||||
this.wires[idxPair] = true;
|
||||
if (i === this.testRegister || j === this.testRegister) {
|
||||
this.energiseCount++;
|
||||
|
@ -516,12 +517,12 @@ export class BombeMachine {
|
|||
}
|
||||
}
|
||||
|
||||
for (let k=0; k<this.scramblers[i].length; k++) {
|
||||
for (let k = 0; k < this.scramblers[i].length; k++) {
|
||||
const scrambler = this.scramblers[i][k];
|
||||
const out = scrambler.transform(j);
|
||||
const other = scrambler.getOtherEnd(i);
|
||||
// Lift the pre-check before the call, to save some function call overhead
|
||||
const otherIdx = 26*other + out;
|
||||
const otherIdx = 26 * other + out;
|
||||
if (!this.wires[otherIdx]) {
|
||||
this.energise(other, out);
|
||||
if (this.energiseCount === 26) {
|
||||
|
@ -532,11 +533,11 @@ export class BombeMachine {
|
|||
if (i === j) {
|
||||
return;
|
||||
}
|
||||
for (let k=0; k<this.scramblers[j].length; k++) {
|
||||
for (let k = 0; k < this.scramblers[j].length; k++) {
|
||||
const scrambler = this.scramblers[j][k];
|
||||
const out = scrambler.transform(i);
|
||||
const other = scrambler.getOtherEnd(j);
|
||||
const otherIdx = 26*other + out;
|
||||
const otherIdx = 26 * other + out;
|
||||
if (!this.wires[otherIdx]) {
|
||||
this.energise(other, out);
|
||||
if (this.energiseCount === 26) {
|
||||
|
@ -561,7 +562,7 @@ export class BombeMachine {
|
|||
const res = [];
|
||||
const plugboard = new Plugboard(stecker);
|
||||
// The indicator scrambler starts in the right place for the beginning of the ciphertext.
|
||||
for (let i=0; i<Math.min(26, this.ciphertext.length); i++) {
|
||||
for (let i = 0; i < Math.min(26, this.ciphertext.length); i++) {
|
||||
const t = this.indicator.transform(plugboard.transform(a2i(this.ciphertext[i])));
|
||||
res.push(i2a(plugboard.transform(t)));
|
||||
this.indicator.step(1);
|
||||
|
@ -602,7 +603,7 @@ export class BombeMachine {
|
|||
if (pair !== this.testInput[1]) {
|
||||
// We have a new hypothesis for this stop - apply the new one.
|
||||
// De-energise the board
|
||||
for (let i=0; i<this.wires.length; i++) {
|
||||
for (let i = 0; i < this.wires.length; i++) {
|
||||
this.wires[i] = false;
|
||||
}
|
||||
this.energiseCount = 0;
|
||||
|
@ -612,11 +613,11 @@ export class BombeMachine {
|
|||
|
||||
const results = new Set();
|
||||
results.add(this.formatPair(this.testRegister, pair));
|
||||
for (let i=0; i<26; i++) {
|
||||
for (let i = 0; i < 26; i++) {
|
||||
let count = 0;
|
||||
let other;
|
||||
for (let j=0; j<26; j++) {
|
||||
if (this.wires[i*26 + j]) {
|
||||
for (let j = 0; j < 26; j++) {
|
||||
if (this.wires[i * 26 + j]) {
|
||||
count++;
|
||||
other = j;
|
||||
}
|
||||
|
@ -649,8 +650,8 @@ export class BombeMachine {
|
|||
// started with are hypothesised to be a stecker pair.
|
||||
if (count === 25) {
|
||||
// Our steckering hypothesis is wrong. Correct value is the un-energised wire.
|
||||
for (let j=0; j<26; j++) {
|
||||
if (!this.wires[26*this.testRegister + j]) {
|
||||
for (let j = 0; j < 26; j++) {
|
||||
if (!this.wires[26 * this.testRegister + j]) {
|
||||
steckerPair = j;
|
||||
break;
|
||||
}
|
||||
|
@ -713,9 +714,9 @@ export class BombeMachine {
|
|||
const result = [];
|
||||
// For each possible rotor setting
|
||||
const nChecks = Math.pow(26, this.baseRotors.length);
|
||||
for (let i=1; i<=nChecks; i++) {
|
||||
for (let i = 1; i <= nChecks; i++) {
|
||||
// Benchmarking suggests this is faster than using .fill()
|
||||
for (let i=0; i<this.wires.length; i++) {
|
||||
for (let i = 0; i < this.wires.length; i++) {
|
||||
this.wires[i] = false;
|
||||
}
|
||||
this.energiseCount = 0;
|
||||
|
@ -732,8 +733,8 @@ export class BombeMachine {
|
|||
// This loop counts how many rotors have reached their starting position (meaning the
|
||||
// next one needs to step as well)
|
||||
let n = 1;
|
||||
for (let j=1; j<this.baseRotors.length; j++) {
|
||||
if ((i % Math.pow(26, j)) === 0) {
|
||||
for (let j = 1; j < this.baseRotors.length; j++) {
|
||||
if (i % Math.pow(26, j) === 0) {
|
||||
n++;
|
||||
} else {
|
||||
break;
|
||||
|
@ -748,7 +749,7 @@ export class BombeMachine {
|
|||
// Send status messages at what seems to be a reasonably sensible frequency
|
||||
// (note this won't be triggered on 3-rotor runs - they run fast enough it doesn't seem necessary)
|
||||
if (n > 3) {
|
||||
this.update(this.nLoops, stops, i/nChecks);
|
||||
this.update(this.nLoops, stops, i / nChecks);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
|
|
|
@ -11,5 +11,5 @@
|
|||
*/
|
||||
export const BRAILLE_LOOKUP = {
|
||||
ascii: " A1B'K2L@CIF/MSP\"E3H9O6R^DJG>NTQ,*5<-U8V.%[$+X!&;:4\\0Z7(_?W]#Y)=",
|
||||
dot6: "⠀⠁⠂⠃⠄⠅⠆⠇⠈⠉⠊⠋⠌⠍⠎⠏⠐⠑⠒⠓⠔⠕⠖⠗⠘⠙⠚⠛⠜⠝⠞⠟⠠⠡⠢⠣⠤⠥⠦⠧⠨⠩⠪⠫⠬⠭⠮⠯⠰⠱⠲⠳⠴⠵⠶⠷⠸⠹⠺⠻⠼⠽⠾⠿"
|
||||
dot6: "⠀⠁⠂⠃⠄⠅⠆⠇⠈⠉⠊⠋⠌⠍⠎⠏⠐⠑⠒⠓⠔⠕⠖⠗⠘⠙⠚⠛⠜⠝⠞⠟⠠⠡⠢⠣⠤⠥⠦⠧⠨⠩⠪⠫⠬⠭⠮⠯⠰⠱⠲⠳⠴⠵⠶⠷⠸⠹⠺⠻⠼⠽⠾⠿"
|
||||
};
|
||||
|
|
|
@ -64,14 +64,14 @@ export function drawBarChart(canvas, scores, xAxisLabel, yAxisLabel, numXLabels,
|
|||
|
||||
// Bar properties
|
||||
const barPadding = graphWidth * 0.003,
|
||||
barWidth = (graphWidth - (barPadding * scores.length)) / scores.length,
|
||||
barWidth = (graphWidth - barPadding * scores.length) / scores.length,
|
||||
max = Math.max.apply(Math, scores);
|
||||
let currX = leftPadding + barPadding;
|
||||
|
||||
// Draw bars
|
||||
ctx.fillStyle = "green";
|
||||
for (let i = 0; i < scores.length; i++) {
|
||||
const h = scores[i] / max * graphHeight;
|
||||
const h = (scores[i] / max) * graphHeight;
|
||||
ctx.fillRect(currX, base - h, barWidth, h);
|
||||
currX += barWidth + barPadding;
|
||||
}
|
||||
|
@ -83,7 +83,7 @@ export function drawBarChart(canvas, scores, xAxisLabel, yAxisLabel, numXLabels,
|
|||
if (numXLabels >= scores.length) {
|
||||
// Mark every score
|
||||
for (let i = 0; i <= scores.length; i++) {
|
||||
ctx.fillText(i, currX, base + (bottomPadding * 0.3));
|
||||
ctx.fillText(i, currX, base + bottomPadding * 0.3);
|
||||
currX += barWidth + barPadding;
|
||||
}
|
||||
} else {
|
||||
|
@ -91,7 +91,7 @@ export function drawBarChart(canvas, scores, xAxisLabel, yAxisLabel, numXLabels,
|
|||
for (let i = 0; i <= numXLabels; i++) {
|
||||
const val = Math.ceil((scores.length / numXLabels) * i);
|
||||
currX = (graphWidth / numXLabels) * i + leftPadding;
|
||||
ctx.fillText(val, currX, base + (bottomPadding * 0.3));
|
||||
ctx.fillText(val, currX, base + bottomPadding * 0.3);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -101,14 +101,14 @@ export function drawBarChart(canvas, scores, xAxisLabel, yAxisLabel, numXLabels,
|
|||
if (numYLabels >= max) {
|
||||
// Mark every increment
|
||||
for (let i = 0; i <= max; i++) {
|
||||
currY = base - (i / max * graphHeight) + fontSize / 3;
|
||||
currY = base - (i / max) * graphHeight + fontSize / 3;
|
||||
ctx.fillText(i, leftPadding * 0.8, currY);
|
||||
}
|
||||
} else {
|
||||
// Mark some increments
|
||||
for (let i = 0; i <= numYLabels; i++) {
|
||||
const val = Math.ceil((max / numYLabels) * i);
|
||||
currY = base - (val / max * graphHeight) + fontSize / 3;
|
||||
currY = base - (val / max) * graphHeight + fontSize / 3;
|
||||
ctx.fillText(val, leftPadding * 0.8, currY);
|
||||
}
|
||||
}
|
||||
|
@ -171,21 +171,21 @@ export function drawScaleBar(canvas, score, max, markings) {
|
|||
ctx.font = "13px Arial";
|
||||
for (let i = 0; i < markings.length; i++) {
|
||||
// Draw min line down
|
||||
x0 = barWidth / max * markings[i].min + leftPadding;
|
||||
y0 = topPadding + barHeight + (bottomPadding * 0.1);
|
||||
x0 = (barWidth / max) * markings[i].min + leftPadding;
|
||||
y0 = topPadding + barHeight + bottomPadding * 0.1;
|
||||
x1 = x0;
|
||||
y1 = topPadding + barHeight + (bottomPadding * 0.3);
|
||||
y1 = topPadding + barHeight + bottomPadding * 0.3;
|
||||
drawLine(ctx, x0, y0, x1, y1);
|
||||
|
||||
// Draw max line down
|
||||
x0 = barWidth / max * markings[i].max + leftPadding;
|
||||
x0 = (barWidth / max) * markings[i].max + leftPadding;
|
||||
x1 = x0;
|
||||
drawLine(ctx, x0, y0, x1, y1);
|
||||
|
||||
// Join min and max lines
|
||||
x0 = barWidth / max * markings[i].min + leftPadding;
|
||||
y0 = topPadding + barHeight + (bottomPadding * 0.3);
|
||||
x1 = barWidth / max * markings[i].max + leftPadding;
|
||||
x0 = (barWidth / max) * markings[i].min + leftPadding;
|
||||
y0 = topPadding + barHeight + bottomPadding * 0.3;
|
||||
x1 = (barWidth / max) * markings[i].max + leftPadding;
|
||||
y1 = y0;
|
||||
drawLine(ctx, x0, y0, x1, y1);
|
||||
|
||||
|
@ -198,7 +198,7 @@ export function drawScaleBar(canvas, score, max, markings) {
|
|||
} else {
|
||||
x0 = x0 + (x1 - x0) / 2;
|
||||
}
|
||||
y0 = topPadding + barHeight + (bottomPadding * 0.8);
|
||||
y0 = topPadding + barHeight + bottomPadding * 0.8;
|
||||
ctx.fillText(markings[i].label, x0, y0);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,14 +14,12 @@ import Utils from "../Utils.mjs";
|
|||
*/
|
||||
export const RECORD_DELIMITER_OPTIONS = ["Line feed", "CRLF"];
|
||||
|
||||
|
||||
/**
|
||||
* @constant
|
||||
* @default
|
||||
*/
|
||||
export const FIELD_DELIMITER_OPTIONS = ["Space", "Comma", "Semi-colon", "Colon", "Tab"];
|
||||
|
||||
|
||||
/**
|
||||
* Default from colour
|
||||
*
|
||||
|
@ -33,7 +31,6 @@ export const COLOURS = {
|
|||
max: "black"
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Gets values from input for a plot.
|
||||
*
|
||||
|
@ -48,22 +45,19 @@ export function getValues(input, recordDelimiter, fieldDelimiter, columnHeadings
|
|||
let headings;
|
||||
const values = [];
|
||||
|
||||
input
|
||||
.split(recordDelimiter)
|
||||
.forEach((row, rowIndex) => {
|
||||
const split = row.split(fieldDelimiter);
|
||||
if (split.length !== length) throw new OperationError(`Each row must have length ${length}.`);
|
||||
input.split(recordDelimiter).forEach((row, rowIndex) => {
|
||||
const split = row.split(fieldDelimiter);
|
||||
if (split.length !== length) throw new OperationError(`Each row must have length ${length}.`);
|
||||
|
||||
if (columnHeadingsAreIncluded && rowIndex === 0) {
|
||||
headings = split;
|
||||
} else {
|
||||
values.push(split);
|
||||
}
|
||||
});
|
||||
if (columnHeadingsAreIncluded && rowIndex === 0) {
|
||||
headings = split;
|
||||
} else {
|
||||
values.push(split);
|
||||
}
|
||||
});
|
||||
return { headings, values };
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets values from input for a scatter plot.
|
||||
*
|
||||
|
@ -74,19 +68,13 @@ export function getValues(input, recordDelimiter, fieldDelimiter, columnHeadings
|
|||
* @returns {Object[]}
|
||||
*/
|
||||
export function getScatterValues(input, recordDelimiter, fieldDelimiter, columnHeadingsAreIncluded) {
|
||||
let { headings, values } = getValues(
|
||||
input,
|
||||
recordDelimiter,
|
||||
fieldDelimiter,
|
||||
columnHeadingsAreIncluded,
|
||||
2
|
||||
);
|
||||
let { headings, values } = getValues(input, recordDelimiter, fieldDelimiter, columnHeadingsAreIncluded, 2);
|
||||
|
||||
if (headings) {
|
||||
headings = {x: headings[0], y: headings[1]};
|
||||
headings = { x: headings[0], y: headings[1] };
|
||||
}
|
||||
|
||||
values = values.map(row => {
|
||||
values = values.map((row) => {
|
||||
const x = parseFloat(row[0]),
|
||||
y = parseFloat(row[1]);
|
||||
|
||||
|
@ -99,7 +87,6 @@ export function getScatterValues(input, recordDelimiter, fieldDelimiter, columnH
|
|||
return { headings, values };
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets values from input for a scatter plot with colour from the third column.
|
||||
*
|
||||
|
@ -110,18 +97,13 @@ export function getScatterValues(input, recordDelimiter, fieldDelimiter, columnH
|
|||
* @returns {Object[]}
|
||||
*/
|
||||
export function getScatterValuesWithColour(input, recordDelimiter, fieldDelimiter, columnHeadingsAreIncluded) {
|
||||
let { headings, values } = getValues(
|
||||
input,
|
||||
recordDelimiter, fieldDelimiter,
|
||||
columnHeadingsAreIncluded,
|
||||
3
|
||||
);
|
||||
let { headings, values } = getValues(input, recordDelimiter, fieldDelimiter, columnHeadingsAreIncluded, 3);
|
||||
|
||||
if (headings) {
|
||||
headings = {x: headings[0], y: headings[1]};
|
||||
headings = { x: headings[0], y: headings[1] };
|
||||
}
|
||||
|
||||
values = values.map(row => {
|
||||
values = values.map((row) => {
|
||||
const x = parseFloat(row[0]),
|
||||
y = parseFloat(row[1]),
|
||||
colour = row[2];
|
||||
|
@ -145,17 +127,12 @@ export function getScatterValuesWithColour(input, recordDelimiter, fieldDelimite
|
|||
* @returns {Object[]}
|
||||
*/
|
||||
export function getSeriesValues(input, recordDelimiter, fieldDelimiter, columnHeadingsAreIncluded) {
|
||||
const { values } = getValues(
|
||||
input,
|
||||
recordDelimiter, fieldDelimiter,
|
||||
false,
|
||||
3
|
||||
);
|
||||
const { values } = getValues(input, recordDelimiter, fieldDelimiter, false, 3);
|
||||
|
||||
let xValues = new Set();
|
||||
const series = {};
|
||||
|
||||
values.forEach(row => {
|
||||
values.forEach((row) => {
|
||||
const serie = row[0],
|
||||
xVal = row[1],
|
||||
val = parseFloat(row[2]);
|
||||
|
@ -172,7 +149,7 @@ export function getSeriesValues(input, recordDelimiter, fieldDelimiter, columnHe
|
|||
const seriesList = [];
|
||||
for (const seriesName in series) {
|
||||
const serie = series[seriesName];
|
||||
seriesList.push({name: seriesName, data: serie});
|
||||
seriesList.push({ name: seriesName, data: serie });
|
||||
}
|
||||
|
||||
return { xValues, series: seriesList };
|
||||
|
|
|
@ -163,10 +163,9 @@ export const CHR_ENC_CODE_PAGES = {
|
|||
"Europa 3 (29001)": 29001,
|
||||
"Atari ST/TT (47451)": 47451,
|
||||
"HZ-GB2312 Simplified Chinese (52936)": 52936,
|
||||
"Simplified Chinese GB18030 (54936)": 54936,
|
||||
"Simplified Chinese GB18030 (54936)": 54936
|
||||
};
|
||||
|
||||
|
||||
export const CHR_ENC_SIMPLE_LOOKUP = {};
|
||||
export const CHR_ENC_SIMPLE_REVERSE_LOOKUP = {};
|
||||
|
||||
|
@ -177,7 +176,6 @@ for (const name in CHR_ENC_CODE_PAGES) {
|
|||
CHR_ENC_SIMPLE_REVERSE_LOOKUP[CHR_ENC_CODE_PAGES[name]] = simpleName;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the width of the character set for the given codepage.
|
||||
* For example, UTF-8 is a Single Byte Character Set, whereas
|
||||
|
@ -194,18 +192,14 @@ export function chrEncWidth(page) {
|
|||
|
||||
const pageStr = page.toString();
|
||||
// Confirm this page is legitimate
|
||||
if (!Object.prototype.hasOwnProperty.call(CHR_ENC_SIMPLE_REVERSE_LOOKUP, pageStr))
|
||||
return 0;
|
||||
if (!Object.prototype.hasOwnProperty.call(CHR_ENC_SIMPLE_REVERSE_LOOKUP, pageStr)) return 0;
|
||||
|
||||
// Statically defined code pages
|
||||
if (Object.prototype.hasOwnProperty.call(cptable, pageStr))
|
||||
return cptable[pageStr].dec.length > 256 ? 2 : 1;
|
||||
if (Object.prototype.hasOwnProperty.call(cptable, pageStr)) return cptable[pageStr].dec.length > 256 ? 2 : 1;
|
||||
|
||||
// Cached code pages
|
||||
if (cptable.utils.cache.sbcs.includes(pageStr))
|
||||
return 1;
|
||||
if (cptable.utils.cache.dbcs.includes(pageStr))
|
||||
return 2;
|
||||
if (cptable.utils.cache.sbcs.includes(pageStr)) return 1;
|
||||
if (cptable.utils.cache.dbcs.includes(pageStr)) return 2;
|
||||
|
||||
// Dynamically generated code pages
|
||||
if (Object.prototype.hasOwnProperty.call(cptable.utils.magic, pageStr)) {
|
||||
|
|
|
@ -6,14 +6,14 @@
|
|||
export function encode(tempIVP, key, rounds, input) {
|
||||
const ivp = new Uint8Array(key.concat(tempIVP));
|
||||
const state = new Array(256).fill(0);
|
||||
let j = 0, i = 0;
|
||||
let j = 0,
|
||||
i = 0;
|
||||
const result = [];
|
||||
|
||||
// Mixing states based off of IV.
|
||||
for (let i = 0; i < 256; i++)
|
||||
state[i] = i;
|
||||
for (let i = 0; i < 256; i++) state[i] = i;
|
||||
const ivpLength = ivp.length;
|
||||
for (let r = 0; r < rounds; r ++) {
|
||||
for (let r = 0; r < rounds; r++) {
|
||||
for (let k = 0; k < 256; k++) {
|
||||
j = (j + state[k] + ivp[k % ivpLength]) % 256;
|
||||
[state[k], state[j]] = [state[j], state[k]];
|
||||
|
@ -24,7 +24,7 @@ export function encode(tempIVP, key, rounds, input) {
|
|||
|
||||
// XOR cipher with key.
|
||||
for (let x = 0; x < input.length; x++) {
|
||||
i = (++i) % 256;
|
||||
i = ++i % 256;
|
||||
j = (j + state[i]) % 256;
|
||||
[state[i], state[j]] = [state[j], state[i]];
|
||||
const n = (state[i] + state[j]) % 256;
|
||||
|
|
|
@ -33,10 +33,10 @@ export function affineEncode(input, args) {
|
|||
for (let i = 0; i < input.length; i++) {
|
||||
if (alphabet.indexOf(input[i]) >= 0) {
|
||||
// Uses the affine function ax+b % m = y (where m is length of the alphabet)
|
||||
output += alphabet[((a * alphabet.indexOf(input[i])) + b) % 26];
|
||||
output += alphabet[(a * alphabet.indexOf(input[i]) + b) % 26];
|
||||
} else if (alphabet.indexOf(input[i].toLowerCase()) >= 0) {
|
||||
// Same as above, accounting for uppercase
|
||||
output += alphabet[((a * alphabet.indexOf(input[i].toLowerCase())) + b) % 26].toUpperCase();
|
||||
output += alphabet[(a * alphabet.indexOf(input[i].toLowerCase()) + b) % 26].toUpperCase();
|
||||
} else {
|
||||
// Non-alphabetic characters
|
||||
output += input[i];
|
||||
|
@ -53,13 +53,13 @@ export function affineEncode(input, args) {
|
|||
* @param {string} keyword - Must be upper case
|
||||
* @returns {string}
|
||||
*/
|
||||
export function genPolybiusSquare (keyword) {
|
||||
export function genPolybiusSquare(keyword) {
|
||||
const alpha = "ABCDEFGHIKLMNOPQRSTUVWXYZ",
|
||||
polArray = `${keyword}${alpha}`.split("").unique(),
|
||||
polybius = [];
|
||||
|
||||
for (let i = 0; i < 5; i++) {
|
||||
polybius[i] = polArray.slice(i*5, i*5 + 5);
|
||||
polybius[i] = polArray.slice(i * 5, i * 5 + 5);
|
||||
}
|
||||
|
||||
return polybius;
|
||||
|
@ -72,11 +72,11 @@ export function genPolybiusSquare (keyword) {
|
|||
* @constant
|
||||
*/
|
||||
export const format = {
|
||||
"Hex": CryptoJS.enc.Hex,
|
||||
"Base64": CryptoJS.enc.Base64,
|
||||
"UTF8": CryptoJS.enc.Utf8,
|
||||
"UTF16": CryptoJS.enc.Utf16,
|
||||
"Hex": CryptoJS.enc.Hex,
|
||||
"Base64": CryptoJS.enc.Base64,
|
||||
"UTF8": CryptoJS.enc.Utf8,
|
||||
"UTF16": CryptoJS.enc.Utf16,
|
||||
"UTF16LE": CryptoJS.enc.Utf16LE,
|
||||
"UTF16BE": CryptoJS.enc.Utf16BE,
|
||||
"Latin1": CryptoJS.enc.Latin1,
|
||||
"Latin1": CryptoJS.enc.Latin1
|
||||
};
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
* @returns {string}
|
||||
*/
|
||||
export function replaceVariableNames(input, replacer) {
|
||||
const tokenRegex = /\\"|"(?:\\"|[^"])*"|(\b[a-z0-9\-_]+\b)/ig;
|
||||
const tokenRegex = /\\"|"(?:\\"|[^"])*"|(\b[a-z0-9\-_]+\b)/gi;
|
||||
|
||||
return input.replace(tokenRegex, (...args) => {
|
||||
const match = args[0],
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
* @copyright Crown Copyright 2019
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
import {INIT_PATTERNS, ITA2_TABLE, ROTOR_SIZES} from "../lib/Lorenz.mjs";
|
||||
import { INIT_PATTERNS, ITA2_TABLE, ROTOR_SIZES } from "../lib/Lorenz.mjs";
|
||||
|
||||
/**
|
||||
* Colossus simulator class.
|
||||
|
@ -39,7 +39,6 @@ export class ColossusComputer {
|
|||
this.settotal = settotal;
|
||||
this.limitations = limit;
|
||||
|
||||
|
||||
this.allCounters = [0, 0, 0, 0, 0];
|
||||
|
||||
this.Zbits = [0, 0, 0, 0, 0]; // Z input is the cipher tape
|
||||
|
@ -73,7 +72,20 @@ export class ColossusComputer {
|
|||
};
|
||||
|
||||
// loop until our start positions are back to the beginning
|
||||
this.rotorPtrs = {X1: this.starts.X1, X2: this.starts.X2, X3: this.starts.X3, X4: this.starts.X4, X5: this.starts.X5, M61: this.starts.M61, M37: this.starts.M37, S1: this.starts.S1, S2: this.starts.S2, S3: this.starts.S3, S4: this.starts.S4, S5: this.starts.S5};
|
||||
this.rotorPtrs = {
|
||||
X1: this.starts.X1,
|
||||
X2: this.starts.X2,
|
||||
X3: this.starts.X3,
|
||||
X4: this.starts.X4,
|
||||
X5: this.starts.X5,
|
||||
M61: this.starts.M61,
|
||||
M37: this.starts.M37,
|
||||
S1: this.starts.S1,
|
||||
S2: this.starts.S2,
|
||||
S3: this.starts.S3,
|
||||
S4: this.starts.S4,
|
||||
S5: this.starts.S5
|
||||
};
|
||||
// this.rotorPtrs = this.starts;
|
||||
let runcount = 1;
|
||||
|
||||
|
@ -97,9 +109,9 @@ export class ColossusComputer {
|
|||
if (fast !== "") fastRef = this.rotorPtrs[fast].toString().padStart(2, "0");
|
||||
if (slow !== "") slowRef = this.rotorPtrs[slow].toString().padStart(2, "0");
|
||||
let printline = "";
|
||||
for (let c=0;c<5;c++) {
|
||||
for (let c = 0; c < 5; c++) {
|
||||
if (this.allCounters[c] > this.settotal) {
|
||||
printline += String.fromCharCode(c+97) + this.allCounters[c]+" ";
|
||||
printline += String.fromCharCode(c + 97) + this.allCounters[c] + " ";
|
||||
}
|
||||
}
|
||||
if (printline !== "") {
|
||||
|
@ -140,7 +152,7 @@ export class ColossusComputer {
|
|||
this.Sptr = [this.rotorPtrs.S1, this.rotorPtrs.S2, this.rotorPtrs.S3, this.rotorPtrs.S4, this.rotorPtrs.S5];
|
||||
|
||||
// Run full loop of all character on the input tape (Z)
|
||||
for (let i=0; i<this.ciphertext.length; i++) {
|
||||
for (let i = 0; i < this.ciphertext.length; i++) {
|
||||
charZin = this.ciphertext.charAt(i);
|
||||
|
||||
// Firstly, we check what inputs are specified on the Q-bus input switches
|
||||
|
@ -164,7 +176,6 @@ export class ColossusComputer {
|
|||
|
||||
// Step rotors
|
||||
this.stepThyratrons();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -175,44 +186,44 @@ export class ColossusComputer {
|
|||
* Psi rotors only step dependant on M37 setting + limitation
|
||||
*/
|
||||
stepThyratrons() {
|
||||
let X2bPtr = this.Xptr[1]-1;
|
||||
if (X2bPtr===0) X2bPtr = ROTOR_SIZES.X2;
|
||||
let S1bPtr = this.Sptr[0]-1;
|
||||
if (S1bPtr===0) S1bPtr = ROTOR_SIZES.S1;
|
||||
let X2bPtr = this.Xptr[1] - 1;
|
||||
if (X2bPtr === 0) X2bPtr = ROTOR_SIZES.X2;
|
||||
let S1bPtr = this.Sptr[0] - 1;
|
||||
if (S1bPtr === 0) S1bPtr = ROTOR_SIZES.S1;
|
||||
|
||||
// Get Chi rotor 5 two back to calculate plaintext (Z+Chi+Psi=Plain)
|
||||
let X5bPtr=this.Xptr[4]-1;
|
||||
if (X5bPtr===0) X5bPtr=ROTOR_SIZES.X5;
|
||||
X5bPtr=X5bPtr-1;
|
||||
if (X5bPtr===0) X5bPtr=ROTOR_SIZES.X5;
|
||||
let X5bPtr = this.Xptr[4] - 1;
|
||||
if (X5bPtr === 0) X5bPtr = ROTOR_SIZES.X5;
|
||||
X5bPtr = X5bPtr - 1;
|
||||
if (X5bPtr === 0) X5bPtr = ROTOR_SIZES.X5;
|
||||
// Get Psi rotor 5 two back to calculate plaintext (Z+Chi+Psi=Plain)
|
||||
let S5bPtr=this.Sptr[4]-1;
|
||||
if (S5bPtr===0) S5bPtr=ROTOR_SIZES.S5;
|
||||
S5bPtr=S5bPtr-1;
|
||||
if (S5bPtr===0) S5bPtr=ROTOR_SIZES.S5;
|
||||
let S5bPtr = this.Sptr[4] - 1;
|
||||
if (S5bPtr === 0) S5bPtr = ROTOR_SIZES.S5;
|
||||
S5bPtr = S5bPtr - 1;
|
||||
if (S5bPtr === 0) S5bPtr = ROTOR_SIZES.S5;
|
||||
|
||||
const x2sw = this.limitations.X2;
|
||||
const s1sw = this.limitations.S1;
|
||||
const p5sw = this.limitations.P5;
|
||||
|
||||
// Limitation calculations
|
||||
let lim=1;
|
||||
if (x2sw) lim = this.rings.X[2][X2bPtr-1];
|
||||
if (s1sw) lim = lim ^ this.rings.S[1][S1bPtr-1];
|
||||
let lim = 1;
|
||||
if (x2sw) lim = this.rings.X[2][X2bPtr - 1];
|
||||
if (s1sw) lim = lim ^ this.rings.S[1][S1bPtr - 1];
|
||||
|
||||
// P5
|
||||
if (p5sw) {
|
||||
let p5lim = this.P5Zbit[1];
|
||||
p5lim = p5lim ^ this.rings.X[5][X5bPtr-1];
|
||||
p5lim = p5lim ^ this.rings.S[5][S5bPtr-1];
|
||||
p5lim = p5lim ^ this.rings.X[5][X5bPtr - 1];
|
||||
p5lim = p5lim ^ this.rings.S[5][S5bPtr - 1];
|
||||
lim = lim ^ p5lim;
|
||||
}
|
||||
|
||||
const basicmotor = this.rings.M[2][this.Mptr[0]-1];
|
||||
const basicmotor = this.rings.M[2][this.Mptr[0] - 1];
|
||||
this.totalmotor = basicmotor;
|
||||
|
||||
if (x2sw || s1sw) {
|
||||
if (basicmotor===0 && lim===1) {
|
||||
if (basicmotor === 0 && lim === 1) {
|
||||
this.totalmotor = 0;
|
||||
} else {
|
||||
this.totalmotor = 1;
|
||||
|
@ -220,26 +231,26 @@ export class ColossusComputer {
|
|||
}
|
||||
|
||||
// Step Chi rotors
|
||||
for (let r=0; r<5; r++) {
|
||||
for (let r = 0; r < 5; r++) {
|
||||
this.Xptr[r]++;
|
||||
if (this.Xptr[r] > ROTOR_SIZES["X"+(r+1)]) this.Xptr[r] = 1;
|
||||
if (this.Xptr[r] > ROTOR_SIZES["X" + (r + 1)]) this.Xptr[r] = 1;
|
||||
}
|
||||
|
||||
if (this.totalmotor) {
|
||||
// Step Psi rotors
|
||||
for (let r=0; r<5; r++) {
|
||||
for (let r = 0; r < 5; r++) {
|
||||
this.Sptr[r]++;
|
||||
if (this.Sptr[r] > ROTOR_SIZES["S"+(r+1)]) this.Sptr[r] = 1;
|
||||
if (this.Sptr[r] > ROTOR_SIZES["S" + (r + 1)]) this.Sptr[r] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Move M37 rotor if M61 set
|
||||
if (this.rings.M[1][this.Mptr[1]-1]===1) this.Mptr[0]++;
|
||||
if (this.Mptr[0] > ROTOR_SIZES.M37) this.Mptr[0]=1;
|
||||
if (this.rings.M[1][this.Mptr[1] - 1] === 1) this.Mptr[0]++;
|
||||
if (this.Mptr[0] > ROTOR_SIZES.M37) this.Mptr[0] = 1;
|
||||
|
||||
// Always move M61 rotor
|
||||
this.Mptr[1]++;
|
||||
if (this.Mptr[1] > ROTOR_SIZES.M61) this.Mptr[1]=1;
|
||||
if (this.Mptr[1] > ROTOR_SIZES.M61) this.Mptr[1] = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -253,25 +264,25 @@ export class ColossusComputer {
|
|||
this.Qbits = this.Zbits;
|
||||
} else if (this.qbusin.Z === "ΔZ") {
|
||||
// delta Z, the Bitwise XOR of this character Zbits + last character Zbits
|
||||
for (let b=0;b<5;b++) {
|
||||
for (let b = 0; b < 5; b++) {
|
||||
this.Qbits[b] = this.Zbits[b] ^ this.ZbitsOneBack[b];
|
||||
}
|
||||
}
|
||||
this.ZbitsOneBack = this.Zbits.slice(); // copy value of object, not reference
|
||||
|
||||
// Xbits - the current Chi wheel bits
|
||||
for (let b=0;b<5;b++) {
|
||||
this.Xbits[b] = this.rings.X[b+1][this.Xptr[b]-1];
|
||||
for (let b = 0; b < 5; b++) {
|
||||
this.Xbits[b] = this.rings.X[b + 1][this.Xptr[b] - 1];
|
||||
}
|
||||
if (this.qbusin.Chi !== "") {
|
||||
if (this.qbusin.Chi === "Χ") {
|
||||
// direct X added to Qbits
|
||||
for (let b=0;b<5;b++) {
|
||||
for (let b = 0; b < 5; b++) {
|
||||
this.Qbits[b] = this.Qbits[b] ^ this.Xbits[b];
|
||||
}
|
||||
} else if (this.qbusin.Chi === "ΔΧ") {
|
||||
// delta X
|
||||
for (let b=0;b<5;b++) {
|
||||
for (let b = 0; b < 5; b++) {
|
||||
this.Qbits[b] = this.Qbits[b] ^ this.Xbits[b];
|
||||
this.Qbits[b] = this.Qbits[b] ^ this.XbitsOneBack[b];
|
||||
}
|
||||
|
@ -280,18 +291,18 @@ export class ColossusComputer {
|
|||
this.XbitsOneBack = this.Xbits.slice();
|
||||
|
||||
// Sbits - the current Psi wheel bits
|
||||
for (let b=0;b<5;b++) {
|
||||
this.Sbits[b] = this.rings.S[b+1][this.Sptr[b]-1];
|
||||
for (let b = 0; b < 5; b++) {
|
||||
this.Sbits[b] = this.rings.S[b + 1][this.Sptr[b] - 1];
|
||||
}
|
||||
if (this.qbusin.Psi !== "") {
|
||||
if (this.qbusin.Psi === "Ψ") {
|
||||
// direct S added to Qbits
|
||||
for (let b=0;b<5;b++) {
|
||||
for (let b = 0; b < 5; b++) {
|
||||
this.Qbits[b] = this.Qbits[b] ^ this.Sbits[b];
|
||||
}
|
||||
} else if (this.qbusin.Psi === "ΔΨ") {
|
||||
// delta S
|
||||
for (let b=0;b<5;b++) {
|
||||
for (let b = 0; b < 5; b++) {
|
||||
this.Qbits[b] = this.Qbits[b] ^ this.Sbits[b];
|
||||
this.Qbits[b] = this.Qbits[b] ^ this.SbitsOneBack[b];
|
||||
}
|
||||
|
@ -307,14 +318,14 @@ export class ColossusComputer {
|
|||
const cnt = [-1, -1, -1, -1, -1];
|
||||
const numrows = this.qbusswitches.condition.length;
|
||||
|
||||
for (let r=0;r<numrows;r++) {
|
||||
for (let r = 0; r < numrows; r++) {
|
||||
const row = this.qbusswitches.condition[r];
|
||||
if (row.Counter !== "") {
|
||||
let result = true;
|
||||
const cPnt = row.Counter-1;
|
||||
const cPnt = row.Counter - 1;
|
||||
const Qswitch = this.readBusSwitches(row.Qswitches);
|
||||
// Match switches to bit pattern
|
||||
for (let s=0;s<5;s++) {
|
||||
for (let s = 0; s < 5; s++) {
|
||||
if (Qswitch[s] >= 0 && Qswitch[s] !== parseInt(this.Qbits[s], 10)) result = false;
|
||||
}
|
||||
// Check for NOT switch
|
||||
|
@ -330,7 +341,7 @@ export class ColossusComputer {
|
|||
}
|
||||
|
||||
// Negate the whole column, this allows A OR B by doing NOT(NOT A AND NOT B)
|
||||
for (let c=0;c<5;c++) {
|
||||
for (let c = 0; c < 5; c++) {
|
||||
if (this.qbusswitches.condNegateAll && cnt[c] !== -1) cnt[c] = !cnt[c];
|
||||
}
|
||||
|
||||
|
@ -348,13 +359,13 @@ export class ColossusComputer {
|
|||
// Colossus could actually add into any of the five counters.
|
||||
if (row.C1) {
|
||||
let addition = 0;
|
||||
for (let s=0;s<5;s++) {
|
||||
for (let s = 0; s < 5; s++) {
|
||||
// XOR addition
|
||||
if (Qswitch[s]) {
|
||||
addition = addition ^ this.Qbits[s];
|
||||
}
|
||||
}
|
||||
const equals = (row.Equals===""?-1:(row.Equals==="."?0:1));
|
||||
const equals = row.Equals === "" ? -1 : row.Equals === "." ? 0 : 1;
|
||||
if (addition === equals) {
|
||||
// AND with conditional rows to get final result
|
||||
if (cnt[0] === -1) cnt[0] = true;
|
||||
|
@ -365,13 +376,16 @@ export class ColossusComputer {
|
|||
|
||||
// Final check, check for addition section negate
|
||||
// then, if any column set, from top to bottom of rack, add to counter.
|
||||
for (let c=0;c<5;c++) {
|
||||
for (let c = 0; c < 5; c++) {
|
||||
if (this.qbusswitches.addNegateAll && cnt[c] !== -1) cnt[c] = !cnt[c];
|
||||
|
||||
if (this.qbusswitches.totalMotor === "" || (this.qbusswitches.totalMotor === "x" && this.totalmotor === 0) || (this.qbusswitches.totalMotor === "." && this.totalmotor === 1)) {
|
||||
if (
|
||||
this.qbusswitches.totalMotor === ""
|
||||
|| (this.qbusswitches.totalMotor === "x" && this.totalmotor === 0)
|
||||
|| (this.qbusswitches.totalMotor === "." && this.totalmotor === 1)
|
||||
) {
|
||||
if (cnt[c] === true) this.allCounters[c]++;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -390,7 +404,7 @@ export class ColossusComputer {
|
|||
},
|
||||
M: {
|
||||
1: INIT_PATTERNS[pattern].M[1].slice().reverse(),
|
||||
2: INIT_PATTERNS[pattern].M[2].slice().reverse(),
|
||||
2: INIT_PATTERNS[pattern].M[2].slice().reverse()
|
||||
},
|
||||
S: {
|
||||
1: INIT_PATTERNS[pattern].S[1].slice().reverse(),
|
||||
|
@ -407,11 +421,10 @@ export class ColossusComputer {
|
|||
*/
|
||||
readBusSwitches(row) {
|
||||
const output = [-1, -1, -1, -1, -1];
|
||||
for (let c=0;c<5;c++) {
|
||||
if (row[c]===".") output[c] = 0;
|
||||
if (row[c]==="x") output[c] = 1;
|
||||
for (let c = 0; c < 5; c++) {
|
||||
if (row[c] === ".") output[c] = 0;
|
||||
if (row[c] === "x") output[c] = 1;
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -43,7 +43,7 @@ const NO_CHANGE = [
|
|||
"Geohash",
|
||||
"Military Grid Reference System",
|
||||
"Ordnance Survey National Grid",
|
||||
"Universal Transverse Mercator",
|
||||
"Universal Transverse Mercator"
|
||||
];
|
||||
|
||||
/**
|
||||
|
@ -58,7 +58,7 @@ const NO_CHANGE = [
|
|||
* @param {number} precision - Precision of the result
|
||||
* @returns {string} A formatted string of the converted co-ordinates
|
||||
*/
|
||||
export function convertCoordinates (input, inFormat, inDelim, outFormat, outDelim, includeDir, precision) {
|
||||
export function convertCoordinates(input, inFormat, inDelim, outFormat, outDelim, includeDir, precision) {
|
||||
let isPair = false,
|
||||
split,
|
||||
latlon,
|
||||
|
@ -194,7 +194,7 @@ export function convertCoordinates (input, inFormat, inDelim, outFormat, outDeli
|
|||
break;
|
||||
case "Decimal Degrees":
|
||||
if (isPair) {
|
||||
splitLat = splitInput(split[0]);
|
||||
splitLat = splitInput(split[0]);
|
||||
splitLong = splitInput(split[1]);
|
||||
if (splitLat.length !== 1 || splitLong.length !== 1) {
|
||||
throw new OperationError("Invalid co-ordinate format for Decimal Degrees.");
|
||||
|
@ -221,11 +221,11 @@ export function convertCoordinates (input, inFormat, inDelim, outFormat, outDeli
|
|||
const dirs = input.toUpperCase().match(/[NESW]/g);
|
||||
if (dirs && dirs.length >= 1) {
|
||||
// Make positive lat/lon values with S/W directions into negative values
|
||||
if (dirs[0] === "S" || dirs[0] === "W" && latlon.lat > 0) {
|
||||
if (dirs[0] === "S" || (dirs[0] === "W" && latlon.lat > 0)) {
|
||||
latlon.lat = -latlon.lat;
|
||||
}
|
||||
if (dirs.length >= 2) {
|
||||
if (dirs[1] === "S" || dirs[1] === "W" && latlon.lon > 0) {
|
||||
if (dirs[1] === "S" || (dirs[1] === "W" && latlon.lon > 0)) {
|
||||
latlon.lon = -latlon.lon;
|
||||
}
|
||||
}
|
||||
|
@ -275,7 +275,9 @@ export function convertCoordinates (input, inFormat, inDelim, outFormat, outDeli
|
|||
case "Ordnance Survey National Grid":
|
||||
osng = OsGridRef.latLonToOsGrid(latlon);
|
||||
if (osng.toString() === "") {
|
||||
throw new OperationError("Could not convert co-ordinates to OS National Grid. Are the co-ordinates in range?");
|
||||
throw new OperationError(
|
||||
"Could not convert co-ordinates to OS National Grid. Are the co-ordinates in range?"
|
||||
);
|
||||
}
|
||||
// OSNG wants a precision that's an even number between 2 and 10
|
||||
if (precision % 2 !== 0) {
|
||||
|
@ -340,10 +342,10 @@ export function convertCoordinates (input, inFormat, inDelim, outFormat, outDeli
|
|||
* @param {string} input - The input data to be split
|
||||
* @returns {number[]} An array of the different items in the string, stored as floats
|
||||
*/
|
||||
function splitInput (input) {
|
||||
function splitInput(input) {
|
||||
const split = [];
|
||||
|
||||
input.split(/\s+/).forEach(item => {
|
||||
input.split(/\s+/).forEach((item) => {
|
||||
// Remove any character that isn't a digit, decimal point or negative sign
|
||||
item = item.replace(/[^0-9.-]/g, "");
|
||||
if (item.length > 0) {
|
||||
|
@ -363,9 +365,9 @@ function splitInput (input) {
|
|||
* @param {number} precision - The precision the result should be rounded to
|
||||
* @returns {{string: string, degrees: number}} An object containing the raw converted value (obj.degrees), and a formatted string version (obj.string)
|
||||
*/
|
||||
function convDMSToDD (degrees, minutes, seconds, precision) {
|
||||
function convDMSToDD(degrees, minutes, seconds, precision) {
|
||||
const absDegrees = Math.abs(degrees);
|
||||
let conv = absDegrees + (minutes / 60) + (seconds / 3600);
|
||||
let conv = absDegrees + minutes / 60 + seconds / 3600;
|
||||
let outString = round(conv, precision) + "°";
|
||||
if (isNegativeZero(degrees) || degrees < 0) {
|
||||
conv = -conv;
|
||||
|
@ -385,7 +387,7 @@ function convDMSToDD (degrees, minutes, seconds, precision) {
|
|||
* @param {number} precision - The precision which the result should be rounded to
|
||||
* @returns {{string: string, degrees: number}} An object containing the raw converted value (obj.degrees), and a formatted string version (obj.string)
|
||||
*/
|
||||
function convDDMToDD (degrees, minutes, precision) {
|
||||
function convDDMToDD(degrees, minutes, precision) {
|
||||
const absDegrees = Math.abs(degrees);
|
||||
let conv = absDegrees + minutes / 60;
|
||||
let outString = round(conv, precision) + "°";
|
||||
|
@ -407,7 +409,7 @@ function convDDMToDD (degrees, minutes, precision) {
|
|||
* @param {number} precision - The precision which the result should be rounded to
|
||||
* @returns {{string: string, degrees: number}} An object containing the raw converted value (obj.degrees), and a formatted string version (obj.string)
|
||||
*/
|
||||
function convDDToDD (degrees, precision) {
|
||||
function convDDToDD(degrees, precision) {
|
||||
return {
|
||||
"degrees": degrees,
|
||||
"string": round(degrees, precision) + "°"
|
||||
|
@ -421,12 +423,12 @@ function convDDToDD (degrees, precision) {
|
|||
* @param {number} precision - The precision which the result should be rounded to
|
||||
* @returns {{string: string, degrees: number, minutes: number, seconds: number}} An object containing the raw converted value as separate numbers (.degrees, .minutes, .seconds), and a formatted string version (obj.string)
|
||||
*/
|
||||
function convDDToDMS (decDegrees, precision) {
|
||||
function convDDToDMS(decDegrees, precision) {
|
||||
const absDegrees = Math.abs(decDegrees);
|
||||
let degrees = Math.floor(absDegrees);
|
||||
const minutes = Math.floor(60 * (absDegrees - degrees)),
|
||||
seconds = round(3600 * (absDegrees - degrees) - 60 * minutes, precision);
|
||||
let outString = degrees + "° " + minutes + "' " + seconds + "\"";
|
||||
let outString = degrees + "° " + minutes + "' " + seconds + '"';
|
||||
if (isNegativeZero(decDegrees) || decDegrees < 0) {
|
||||
degrees = -degrees;
|
||||
outString = "-" + outString;
|
||||
|
@ -446,7 +448,7 @@ function convDDToDMS (decDegrees, precision) {
|
|||
* @param {number} precision - The precision the input data should be rounded to
|
||||
* @returns {{string: string, degrees: number, minutes: number}} An object containing the raw converted value as separate numbers (.degrees, .minutes), and a formatted string version (obj.string)
|
||||
*/
|
||||
function convDDToDDM (decDegrees, precision) {
|
||||
function convDDToDDM(decDegrees, precision) {
|
||||
const absDegrees = Math.abs(decDegrees);
|
||||
let degrees = Math.floor(absDegrees);
|
||||
const minutes = absDegrees - degrees,
|
||||
|
@ -460,7 +462,7 @@ function convDDToDDM (decDegrees, precision) {
|
|||
return {
|
||||
"degrees": degrees,
|
||||
"minutes": decMinutes,
|
||||
"string": outString,
|
||||
"string": outString
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -532,7 +534,7 @@ export function findDirs(input, delim) {
|
|||
* @param {string} delim - The delimiter separating the data in input
|
||||
* @returns {string} The input format
|
||||
*/
|
||||
export function findFormat (input, delim) {
|
||||
export function findFormat(input, delim) {
|
||||
let testData;
|
||||
const mgrsPattern = new RegExp(/^[0-9]{2}\s?[C-HJ-NP-X]{1}\s?[A-HJ-NP-Z][A-HJ-NP-V]\s?[0-9\s]+/),
|
||||
osngPattern = new RegExp(/^[A-HJ-Z]{2}\s+[0-9\s]+$/),
|
||||
|
@ -597,7 +599,7 @@ export function findFormat (input, delim) {
|
|||
* @param {string} input
|
||||
* @returns {string} Delimiter type
|
||||
*/
|
||||
export function findDelim (input) {
|
||||
export function findDelim(input) {
|
||||
input = input.trim();
|
||||
const delims = [",", ";", ":"];
|
||||
const testDir = input.match(/[NnEeSsWw]/g);
|
||||
|
@ -634,14 +636,14 @@ export function findDelim (input) {
|
|||
* @param {string} delim The delimiter to be matched
|
||||
* @returns {string}
|
||||
*/
|
||||
export function realDelim (delim) {
|
||||
export function realDelim(delim) {
|
||||
return {
|
||||
"Auto": "Auto",
|
||||
"Space": " ",
|
||||
"\\n": "\n",
|
||||
"Comma": ",",
|
||||
"Semi-colon": ";",
|
||||
"Colon": ":"
|
||||
"Auto": "Auto",
|
||||
"Space": " ",
|
||||
"\\n": "\n",
|
||||
"Comma": ",",
|
||||
"Semi-colon": ";",
|
||||
"Colon": ":"
|
||||
}[delim];
|
||||
}
|
||||
|
||||
|
@ -652,7 +654,7 @@ export function realDelim (delim) {
|
|||
* @returns {boolean}
|
||||
*/
|
||||
function isNegativeZero(zero) {
|
||||
return zero === 0 && (1/zero < 0);
|
||||
return zero === 0 && 1 / zero < 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -6,4 +6,5 @@
|
|||
* @license Apache-2.0
|
||||
*/
|
||||
|
||||
export const cryptNotice = "WARNING: Cryptographic operations in CyberChef should not be relied upon to provide security in any situation. No guarantee is offered for their correctness. We advise you not to use keys generated from CyberChef in operational contexts.";
|
||||
export const cryptNotice
|
||||
= "WARNING: Cryptographic operations in CyberChef should not be relied upon to provide security in any situation. No guarantee is offered for their correctness. We advise you not to use keys generated from CyberChef in operational contexts.";
|
||||
|
|
|
@ -42,7 +42,7 @@ export const DATETIME_FORMATS = [
|
|||
{
|
||||
name: "Automatic",
|
||||
value: ""
|
||||
},
|
||||
}
|
||||
];
|
||||
|
||||
/**
|
||||
|
@ -310,4 +310,3 @@ export const FORMAT_EXAMPLES = `Format string tokens:
|
|||
</tr>
|
||||
</tbody>
|
||||
</table>`;
|
||||
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
|
||||
import Utils from "../Utils.mjs";
|
||||
|
||||
|
||||
/**
|
||||
* Convert a string of decimal values into a byte array.
|
||||
*
|
||||
|
@ -23,12 +22,11 @@ import Utils from "../Utils.mjs";
|
|||
* // returns [10,20,30]
|
||||
* fromDecimal("10:20:30", "Colon");
|
||||
*/
|
||||
export function fromDecimal(data, delim="Auto") {
|
||||
export function fromDecimal(data, delim = "Auto") {
|
||||
delim = Utils.charRep(delim);
|
||||
const output = [];
|
||||
let byteStr = data.split(delim);
|
||||
if (byteStr[byteStr.length-1] === "")
|
||||
byteStr = byteStr.slice(0, byteStr.length-1);
|
||||
if (byteStr[byteStr.length - 1] === "") byteStr = byteStr.slice(0, byteStr.length - 1);
|
||||
|
||||
for (let i = 0; i < byteStr.length; i++) {
|
||||
output[i] = parseInt(byteStr[i], 10);
|
||||
|
|
|
@ -19,7 +19,16 @@ export const BIN_DELIM_OPTIONS = ["Space", "Comma", "Semi-colon", "Colon", "Line
|
|||
/**
|
||||
* Letter sequence delimiters.
|
||||
*/
|
||||
export const LETTER_DELIM_OPTIONS = ["Space", "Line feed", "CRLF", "Forward slash", "Backslash", "Comma", "Semi-colon", "Colon"];
|
||||
export const LETTER_DELIM_OPTIONS = [
|
||||
"Space",
|
||||
"Line feed",
|
||||
"CRLF",
|
||||
"Forward slash",
|
||||
"Backslash",
|
||||
"Comma",
|
||||
"Semi-colon",
|
||||
"Colon"
|
||||
];
|
||||
|
||||
/**
|
||||
* Word sequence delimiters.
|
||||
|
@ -29,7 +38,15 @@ export const WORD_DELIM_OPTIONS = ["Line feed", "CRLF", "Forward slash", "Backsl
|
|||
/**
|
||||
* Input sequence delimiters.
|
||||
*/
|
||||
export const INPUT_DELIM_OPTIONS = ["Line feed", "CRLF", "Space", "Comma", "Semi-colon", "Colon", "Nothing (separate chars)"];
|
||||
export const INPUT_DELIM_OPTIONS = [
|
||||
"Line feed",
|
||||
"CRLF",
|
||||
"Space",
|
||||
"Comma",
|
||||
"Semi-colon",
|
||||
"Colon",
|
||||
"Nothing (separate chars)"
|
||||
];
|
||||
|
||||
/**
|
||||
* Arithmetic sequence delimiters
|
||||
|
@ -50,34 +67,34 @@ export const IP_DELIM_OPTIONS = ["Line feed", "CRLF", "Space", "Comma", "Semi-co
|
|||
* Split delimiters.
|
||||
*/
|
||||
export const SPLIT_DELIM_OPTIONS = [
|
||||
{name: "Comma", value: ","},
|
||||
{name: "Space", value: " "},
|
||||
{name: "Line feed", value: "\\n"},
|
||||
{name: "CRLF", value: "\\r\\n"},
|
||||
{name: "Semi-colon", value: ";"},
|
||||
{name: "Colon", value: ":"},
|
||||
{name: "Nothing (separate chars)", value: ""}
|
||||
{ name: "Comma", value: "," },
|
||||
{ name: "Space", value: " " },
|
||||
{ name: "Line feed", value: "\\n" },
|
||||
{ name: "CRLF", value: "\\r\\n" },
|
||||
{ name: "Semi-colon", value: ";" },
|
||||
{ name: "Colon", value: ":" },
|
||||
{ name: "Nothing (separate chars)", value: "" }
|
||||
];
|
||||
|
||||
/**
|
||||
* Join delimiters.
|
||||
*/
|
||||
export const JOIN_DELIM_OPTIONS = [
|
||||
{name: "Line feed", value: "\\n"},
|
||||
{name: "CRLF", value: "\\r\\n"},
|
||||
{name: "Space", value: " "},
|
||||
{name: "Comma", value: ","},
|
||||
{name: "Semi-colon", value: ";"},
|
||||
{name: "Colon", value: ":"},
|
||||
{name: "Nothing (join chars)", value: ""}
|
||||
{ name: "Line feed", value: "\\n" },
|
||||
{ name: "CRLF", value: "\\r\\n" },
|
||||
{ name: "Space", value: " " },
|
||||
{ name: "Comma", value: "," },
|
||||
{ name: "Semi-colon", value: ";" },
|
||||
{ name: "Colon", value: ":" },
|
||||
{ name: "Nothing (join chars)", value: "" }
|
||||
];
|
||||
|
||||
/**
|
||||
* RGBA list delimiters.
|
||||
*/
|
||||
export const RGBA_DELIM_OPTIONS = [
|
||||
{name: "Comma", value: ","},
|
||||
{name: "Space", value: " "},
|
||||
{name: "CRLF", value: "\\r\\n"},
|
||||
{name: "Line Feed", value: "\n"}
|
||||
{ name: "Comma", value: "," },
|
||||
{ name: "Space", value: " " },
|
||||
{ name: "CRLF", value: "\\r\\n" },
|
||||
{ name: "Line Feed", value: "\n" }
|
||||
];
|
||||
|
|
|
@ -14,19 +14,19 @@ import Utils from "../Utils.mjs";
|
|||
* followed by < and a list of letters at which the rotor steps.
|
||||
*/
|
||||
export const ROTORS = [
|
||||
{name: "I", value: "EKMFLGDQVZNTOWYHXUSPAIBRCJ<R"},
|
||||
{name: "II", value: "AJDKSIRUXBLHWTMCQGZNPYFVOE<F"},
|
||||
{name: "III", value: "BDFHJLCPRTXVZNYEIWGAKMUSQO<W"},
|
||||
{name: "IV", value: "ESOVPZJAYQUIRHXLNFTGKDCMWB<K"},
|
||||
{name: "V", value: "VZBRGITYUPSDNHLXAWMJQOFECK<A"},
|
||||
{name: "VI", value: "JPGVOUMFYQBENHZRDKASXLICTW<AN"},
|
||||
{name: "VII", value: "NZJHGRCXMYSWBOUFAIVLPEKQDT<AN"},
|
||||
{name: "VIII", value: "FKQHTLXOCBJSPDZRAMEWNIUYGV<AN"},
|
||||
{ name: "I", value: "EKMFLGDQVZNTOWYHXUSPAIBRCJ<R" },
|
||||
{ name: "II", value: "AJDKSIRUXBLHWTMCQGZNPYFVOE<F" },
|
||||
{ name: "III", value: "BDFHJLCPRTXVZNYEIWGAKMUSQO<W" },
|
||||
{ name: "IV", value: "ESOVPZJAYQUIRHXLNFTGKDCMWB<K" },
|
||||
{ name: "V", value: "VZBRGITYUPSDNHLXAWMJQOFECK<A" },
|
||||
{ name: "VI", value: "JPGVOUMFYQBENHZRDKASXLICTW<AN" },
|
||||
{ name: "VII", value: "NZJHGRCXMYSWBOUFAIVLPEKQDT<AN" },
|
||||
{ name: "VIII", value: "FKQHTLXOCBJSPDZRAMEWNIUYGV<AN" }
|
||||
];
|
||||
|
||||
export const ROTORS_FOURTH = [
|
||||
{name: "Beta", value: "LEYJVCNIXWPBQMDRTAKZGFUHOS"},
|
||||
{name: "Gamma", value: "FSOKANUERHMBTIYCWLQPZXVGJD"},
|
||||
{ name: "Beta", value: "LEYJVCNIXWPBQMDRTAKZGFUHOS" },
|
||||
{ name: "Gamma", value: "FSOKANUERHMBTIYCWLQPZXVGJD" }
|
||||
];
|
||||
|
||||
/**
|
||||
|
@ -34,10 +34,10 @@ export const ROTORS_FOURTH = [
|
|||
* These are specified as 13 space-separated transposed pairs covering every letter.
|
||||
*/
|
||||
export const REFLECTORS = [
|
||||
{name: "B", value: "AY BR CU DH EQ FS GL IP JX KN MO TZ VW"},
|
||||
{name: "C", value: "AF BV CP DJ EI GO HY KR LZ MX NW TQ SU"},
|
||||
{name: "B Thin", value: "AE BN CK DQ FU GY HW IJ LO MP RX SZ TV"},
|
||||
{name: "C Thin", value: "AR BD CO EJ FN GT HK IV LM PW QZ SX UY"},
|
||||
{ name: "B", value: "AY BR CU DH EQ FS GL IP JX KN MO TZ VW" },
|
||||
{ name: "C", value: "AF BV CP DJ EI GO HY KR LZ MX NW TQ SU" },
|
||||
{ name: "B Thin", value: "AE BN CK DQ FU GY HW IJ LO MP RX SZ TV" },
|
||||
{ name: "C Thin", value: "AR BD CO EJ FN GT HK IV LM PW QZ SX UY" }
|
||||
];
|
||||
|
||||
export const LETTERS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".split("");
|
||||
|
@ -49,7 +49,7 @@ export const LETTERS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".split("");
|
|||
* @param {boolean} permissive - Case insensitive; don't throw errors on other chars.
|
||||
* @returns {number}
|
||||
*/
|
||||
export function a2i(c, permissive=false) {
|
||||
export function a2i(c, permissive = false) {
|
||||
const i = Utils.ord(c);
|
||||
if (i >= 65 && i <= 90) {
|
||||
return i - 65;
|
||||
|
@ -72,7 +72,7 @@ export function a2i(c, permissive=false) {
|
|||
*/
|
||||
export function i2a(i) {
|
||||
if (i >= 0 && i < 26) {
|
||||
return Utils.chr(i+65);
|
||||
return Utils.chr(i + 65);
|
||||
}
|
||||
throw new OperationError("i2a called on value outside 0..25");
|
||||
}
|
||||
|
@ -105,7 +105,7 @@ export class Rotor {
|
|||
this.map = new Array(26);
|
||||
this.revMap = new Array(26);
|
||||
const uniq = {};
|
||||
for (let i=0; i<LETTERS.length; i++) {
|
||||
for (let i = 0; i < LETTERS.length; i++) {
|
||||
const a = a2i(LETTERS[i]);
|
||||
const b = a2i(wiring[i]);
|
||||
this.map[a] = b;
|
||||
|
@ -167,7 +167,7 @@ class PairMapBase {
|
|||
* @param {string} pairs - A whitespace separated string of letter pairs to swap.
|
||||
* @param {string} [name='PairMapBase'] - For errors, the name of this object.
|
||||
*/
|
||||
constructor(pairs, name="PairMapBase") {
|
||||
constructor(pairs, name = "PairMapBase") {
|
||||
// I've chosen to make whitespace significant here to make a) code and
|
||||
// b) inputs easier to read
|
||||
this.pairs = pairs;
|
||||
|
@ -175,11 +175,12 @@ class PairMapBase {
|
|||
if (pairs === "") {
|
||||
return;
|
||||
}
|
||||
pairs.split(/\s+/).forEach(pair => {
|
||||
pairs.split(/\s+/).forEach((pair) => {
|
||||
if (!/^[A-Z]{2}$/.test(pair)) {
|
||||
throw new OperationError(name + " must be a whitespace-separated list of uppercase letter pairs");
|
||||
}
|
||||
const a = a2i(pair[0]), b = a2i(pair[1]);
|
||||
const a = a2i(pair[0]),
|
||||
b = a2i(pair[1]);
|
||||
if (a === b) {
|
||||
// self-stecker
|
||||
return;
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
* @param {boolean} [unique=false] - Whether to unique the results
|
||||
* @returns {string}
|
||||
*/
|
||||
export function search(input, searchRegex, removeRegex=null, sortBy=null, unique=false) {
|
||||
export function search(input, searchRegex, removeRegex = null, sortBy = null, unique = false) {
|
||||
let results = [];
|
||||
let match;
|
||||
|
||||
|
@ -28,8 +28,7 @@ export function search(input, searchRegex, removeRegex=null, sortBy=null, unique
|
|||
searchRegex.lastIndex++;
|
||||
}
|
||||
|
||||
if (removeRegex && removeRegex.test(match[0]))
|
||||
continue;
|
||||
if (removeRegex && removeRegex.test(match[0])) continue;
|
||||
|
||||
results.push(match[0]);
|
||||
}
|
||||
|
@ -45,20 +44,17 @@ export function search(input, searchRegex, removeRegex=null, sortBy=null, unique
|
|||
return results;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* URL regular expression
|
||||
*/
|
||||
const protocol = "[A-Z]+://",
|
||||
hostname = "[-\\w]+(?:\\.\\w[-\\w]*)+",
|
||||
port = ":\\d+",
|
||||
path = "/[^.!,?\"<>\\[\\]{}\\s\\x7F-\\xFF]*" +
|
||||
"(?:[.!,?]+[^.!,?\"<>\\[\\]{}\\s\\x7F-\\xFF]+)*";
|
||||
path = '/[^.!,?"<>\\[\\]{}\\s\\x7F-\\xFF]*' + '(?:[.!,?]+[^.!,?"<>\\[\\]{}\\s\\x7F-\\xFF]+)*';
|
||||
|
||||
export const URL_REGEX = new RegExp(protocol + hostname + "(?:" + port + ")?(?:" + path + ")?", "ig");
|
||||
|
||||
|
||||
/**
|
||||
* Domain name regular expression
|
||||
*/
|
||||
export const DOMAIN_REGEX = /\b((?=[a-z0-9-]{1,63}\.)(xn--)?[a-z0-9]+(-[a-z0-9]+)*\.)+[a-z]{2,63}\b/ig;
|
||||
export const DOMAIN_REGEX = /\b((?=[a-z0-9-]{1,63}\.)(xn--)?[a-z0-9]+(-[a-z0-9]+)*\.)+[a-z]{2,63}\b/gi;
|
||||
|
|
|
@ -23,7 +23,10 @@ export const FILE_SIGNATURES = {
|
|||
0: 0xff,
|
||||
1: 0xd8,
|
||||
2: 0xff,
|
||||
3: [0xc0, 0xc4, 0xdb, 0xdd, 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe7, 0xe8, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xfe]
|
||||
3: [
|
||||
0xc0, 0xc4, 0xdb, 0xdd, 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe7, 0xe8, 0xea, 0xeb, 0xec, 0xed,
|
||||
0xee, 0xfe
|
||||
]
|
||||
},
|
||||
extractor: extractJPEG
|
||||
},
|
||||
|
@ -38,7 +41,7 @@ export const FILE_SIGNATURES = {
|
|||
2: 0x46,
|
||||
3: 0x38, // 8
|
||||
4: [0x37, 0x39], // 7|9
|
||||
5: 0x61 // a
|
||||
5: 0x61 // a
|
||||
},
|
||||
extractor: extractGIF
|
||||
},
|
||||
|
@ -89,7 +92,8 @@ export const FILE_SIGNATURES = {
|
|||
},
|
||||
extractor: null
|
||||
},
|
||||
{ // Place before tiff check
|
||||
{
|
||||
// Place before tiff check
|
||||
name: "Canon CR2 raw image",
|
||||
extension: "cr2",
|
||||
mime: "image/x-canon-cr2",
|
||||
|
@ -273,7 +277,10 @@ export const FILE_SIGNATURES = {
|
|||
1: 0x0,
|
||||
2: 0x1,
|
||||
3: 0x0,
|
||||
4: [0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15],
|
||||
4: [
|
||||
0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0x10, 0x11, 0x12, 0x13,
|
||||
0x14, 0x15
|
||||
],
|
||||
5: 0x0,
|
||||
6: [0x10, 0x20, 0x30, 0x40, 0x80],
|
||||
7: [0x10, 0x20, 0x30, 0x40, 0x80],
|
||||
|
@ -474,7 +481,8 @@ export const FILE_SIGNATURES = {
|
|||
mime: "image/x-targa",
|
||||
description: "",
|
||||
signature: [
|
||||
{ // This signature is not at the beginning of the file. The extractor works backwards.
|
||||
{
|
||||
// This signature is not at the beginning of the file. The extractor works backwards.
|
||||
0: 0x54,
|
||||
1: 0x52,
|
||||
2: 0x55,
|
||||
|
@ -498,7 +506,8 @@ export const FILE_SIGNATURES = {
|
|||
}
|
||||
],
|
||||
"Video": [
|
||||
{ // Place before webm
|
||||
{
|
||||
// Place before webm
|
||||
name: "Matroska Multimedia Container",
|
||||
extension: "mkv",
|
||||
mime: "video/x-matroska",
|
||||
|
@ -528,7 +537,8 @@ export const FILE_SIGNATURES = {
|
|||
},
|
||||
extractor: null
|
||||
},
|
||||
{ // Place before MPEG-4
|
||||
{
|
||||
// Place before MPEG-4
|
||||
name: "Flash MP4 video",
|
||||
extension: "f4v",
|
||||
mime: "video/mp4",
|
||||
|
@ -746,7 +756,7 @@ export const FILE_SIGNATURES = {
|
|||
}
|
||||
],
|
||||
extractor: null
|
||||
},
|
||||
}
|
||||
],
|
||||
"Audio": [
|
||||
{
|
||||
|
@ -984,7 +994,8 @@ export const FILE_SIGNATURES = {
|
|||
},
|
||||
extractor: null
|
||||
},
|
||||
{ // Place before PostScript
|
||||
{
|
||||
// Place before PostScript
|
||||
name: "Adobe PostScript",
|
||||
extension: "ps,eps,ai,pfa",
|
||||
mime: "application/postscript",
|
||||
|
@ -1275,7 +1286,7 @@ export const FILE_SIGNATURES = {
|
|||
57: 0x70
|
||||
},
|
||||
extractor: extractZIP
|
||||
},
|
||||
}
|
||||
],
|
||||
"Applications": [
|
||||
{
|
||||
|
@ -1355,7 +1366,7 @@ export const FILE_SIGNATURES = {
|
|||
signature: {
|
||||
0: [0x43, 0x46],
|
||||
1: 0x57,
|
||||
2: 0x53,
|
||||
2: 0x53
|
||||
},
|
||||
extractor: null
|
||||
},
|
||||
|
@ -1401,7 +1412,7 @@ export const FILE_SIGNATURES = {
|
|||
3: 0x34
|
||||
},
|
||||
extractor: null
|
||||
},
|
||||
}
|
||||
],
|
||||
"Archives": [
|
||||
{
|
||||
|
@ -1654,7 +1665,7 @@ export const FILE_SIGNATURES = {
|
|||
mime: "application/mac-binhex",
|
||||
description: "",
|
||||
signature: {
|
||||
11: 0x6d, // must be converted with BinHex
|
||||
11: 0x6d, // must be converted with BinHex
|
||||
12: 0x75,
|
||||
13: 0x73,
|
||||
14: 0x74,
|
||||
|
@ -1759,7 +1770,7 @@ export const FILE_SIGNATURES = {
|
|||
description: "",
|
||||
signature: {
|
||||
0: 0x50,
|
||||
1: 0x4B,
|
||||
1: 0x4b,
|
||||
2: 0x03,
|
||||
3: 0x04,
|
||||
4: 0x14,
|
||||
|
@ -1795,7 +1806,7 @@ export const FILE_SIGNATURES = {
|
|||
description: "",
|
||||
signature: {
|
||||
0: 0x21,
|
||||
1: 0x3C,
|
||||
1: 0x3c,
|
||||
2: 0x61,
|
||||
3: 0x72,
|
||||
4: 0x63,
|
||||
|
@ -1834,7 +1845,8 @@ export const FILE_SIGNATURES = {
|
|||
},
|
||||
extractor: null
|
||||
},
|
||||
{ // Place before UTF-16 LE text
|
||||
{
|
||||
// Place before UTF-16 LE text
|
||||
name: "UTF-32 LE text",
|
||||
extension: "utf32le",
|
||||
mime: "charset/utf32le",
|
||||
|
@ -1918,7 +1930,7 @@ export const FILE_SIGNATURES = {
|
|||
10: 0x2,
|
||||
34: 0x4c,
|
||||
35: 0x50
|
||||
},
|
||||
}
|
||||
],
|
||||
extractor: null
|
||||
},
|
||||
|
@ -2217,7 +2229,7 @@ export const FILE_SIGNATURES = {
|
|||
14: 0x45,
|
||||
15: 0x00,
|
||||
21: 0x00,
|
||||
22: b => b >= 0x01 && b <= 0x80,
|
||||
22: (b) => b >= 0x01 && b <= 0x80,
|
||||
23: 0x06
|
||||
},
|
||||
extractor: null
|
||||
|
@ -2233,7 +2245,7 @@ export const FILE_SIGNATURES = {
|
|||
14: 0x45,
|
||||
15: 0x00,
|
||||
16: [0x00, 0x01, 0x02, 0x03, 0x04, 0x05],
|
||||
22: b => b >= 0x01 && b <= 0x80,
|
||||
22: (b) => b >= 0x01 && b <= 0x80,
|
||||
23: 0x11
|
||||
},
|
||||
extractor: null
|
||||
|
@ -2319,7 +2331,7 @@ export const FILE_SIGNATURES = {
|
|||
signature: {
|
||||
0: 0x30,
|
||||
1: 0x83,
|
||||
2: b => b !== 0x00,
|
||||
2: (b) => b !== 0x00,
|
||||
5: 0x06,
|
||||
6: 0x09
|
||||
},
|
||||
|
@ -2445,7 +2457,7 @@ export const FILE_SIGNATURES = {
|
|||
7: 0x62,
|
||||
8: 0x61,
|
||||
9: 0x73,
|
||||
10: 0x68,
|
||||
10: 0x68
|
||||
},
|
||||
extractor: null
|
||||
},
|
||||
|
@ -2463,7 +2475,7 @@ export const FILE_SIGNATURES = {
|
|||
5: 0x6e,
|
||||
6: 0x2f,
|
||||
7: 0x73,
|
||||
8: 0x68,
|
||||
8: 0x68
|
||||
},
|
||||
extractor: null
|
||||
},
|
||||
|
@ -2490,7 +2502,7 @@ export const FILE_SIGNATURES = {
|
|||
14: 0x68,
|
||||
15: 0x6f,
|
||||
16: 0x6e,
|
||||
17: [0x32, 0x33, 0xa, 0xd],
|
||||
17: [0x32, 0x33, 0xa, 0xd]
|
||||
},
|
||||
extractor: null
|
||||
},
|
||||
|
@ -2514,7 +2526,7 @@ export const FILE_SIGNATURES = {
|
|||
11: 0x72,
|
||||
12: 0x75,
|
||||
13: 0x62,
|
||||
14: 0x79,
|
||||
14: 0x79
|
||||
},
|
||||
extractor: null
|
||||
},
|
||||
|
@ -2538,7 +2550,7 @@ export const FILE_SIGNATURES = {
|
|||
11: 0x70,
|
||||
12: 0x65,
|
||||
13: 0x72,
|
||||
14: 0x6c,
|
||||
14: 0x6c
|
||||
},
|
||||
extractor: null
|
||||
},
|
||||
|
@ -2552,7 +2564,7 @@ export const FILE_SIGNATURES = {
|
|||
1: 0x3f,
|
||||
2: 0x70,
|
||||
3: 0x68,
|
||||
4: 0x70,
|
||||
4: 0x70
|
||||
},
|
||||
extractor: null
|
||||
},
|
||||
|
@ -2597,7 +2609,6 @@ export const FILE_SIGNATURES = {
|
|||
]
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* JPEG extractor.
|
||||
*
|
||||
|
@ -2610,7 +2621,8 @@ export function extractJPEG(bytes, offset) {
|
|||
|
||||
while (stream.hasMore()) {
|
||||
const marker = stream.getBytes(2);
|
||||
if (marker[0] !== 0xff) throw new Error(`Invalid marker while parsing JPEG at pos ${stream.position}: ${marker}`);
|
||||
if (marker[0] !== 0xff)
|
||||
throw new Error(`Invalid marker while parsing JPEG at pos ${stream.position}: ${marker}`);
|
||||
|
||||
let segmentSize = 0;
|
||||
switch (marker[1]) {
|
||||
|
@ -2701,7 +2713,6 @@ export function extractJPEG(bytes, offset) {
|
|||
throw new Error("Unable to parse JPEG successfully");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* GIF extractor.
|
||||
*
|
||||
|
@ -2730,21 +2741,18 @@ export function extractGIF(bytes, offset) {
|
|||
while (stream.getBytes(2) !== [0x21, 0xf9]) {
|
||||
stream.moveBackwardsBy(2);
|
||||
stream.moveForwardsBy(stream.readInt(1));
|
||||
if (!stream.readInt(1))
|
||||
break;
|
||||
if (!stream.readInt(1)) break;
|
||||
stream.moveBackwardsBy(1);
|
||||
}
|
||||
|
||||
// When the end of the file is [0x00, 0x3b], end.
|
||||
if (stream.readInt(1) === 0x3b)
|
||||
break;
|
||||
if (stream.readInt(1) === 0x3b) break;
|
||||
|
||||
stream.moveForwardsBy(1);
|
||||
}
|
||||
return stream.carve();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Portable executable extractor.
|
||||
* Assumes that the offset refers to an MZ header.
|
||||
|
@ -2812,7 +2820,6 @@ export function extractMZPE(bytes, offset) {
|
|||
return stream.carve();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* PDF extractor.
|
||||
*
|
||||
|
@ -2832,7 +2839,6 @@ export function extractPDF(bytes, offset) {
|
|||
return stream.carve();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* ZIP extractor.
|
||||
*
|
||||
|
@ -2854,7 +2860,6 @@ export function extractZIP(bytes, offset) {
|
|||
return stream.carve();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* MACHO extractor
|
||||
*
|
||||
|
@ -2863,13 +2868,11 @@ export function extractZIP(bytes, offset) {
|
|||
* @returns {Uint8Array}
|
||||
*/
|
||||
export function extractMACHO(bytes, offset) {
|
||||
|
||||
// Magic bytes.
|
||||
const MHCIGAM64 = "207250237254";
|
||||
const MHMAGIC64 = "254237250207";
|
||||
const MHCIGAM = "206250237254";
|
||||
|
||||
|
||||
/**
|
||||
* Checks to see if the file is 64-bit.
|
||||
*
|
||||
|
@ -2880,7 +2883,6 @@ export function extractMACHO(bytes, offset) {
|
|||
return magic === MHCIGAM64 || magic === MHMAGIC64;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Checks the endianness of the file.
|
||||
*
|
||||
|
@ -2891,7 +2893,6 @@ export function extractMACHO(bytes, offset) {
|
|||
return magic === MHCIGAM || magic === MHCIGAM64;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Jumps through segment information and calculates the sum of the segement sizes.
|
||||
*
|
||||
|
@ -2907,12 +2908,10 @@ export function extractMACHO(bytes, offset) {
|
|||
const LCSEGEMENT = 0x1;
|
||||
|
||||
for (let i = 0; i < ncmds; i++) {
|
||||
|
||||
// Move to start of segment.
|
||||
stream.moveTo(offset);
|
||||
const cmd = stream.readInt(4, isSwap);
|
||||
if (cmd === LCSEGEMENT64) {
|
||||
|
||||
// Move to size of segment field.
|
||||
stream.moveTo(offset + 48);
|
||||
|
||||
|
@ -2934,7 +2933,6 @@ export function extractMACHO(bytes, offset) {
|
|||
return total;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Reads the number of command segments.
|
||||
*
|
||||
|
@ -2945,8 +2943,7 @@ export function extractMACHO(bytes, offset) {
|
|||
*/
|
||||
function dumpMachHeader(stream, is64, isSwap) {
|
||||
let loadCommandsOffset = 28;
|
||||
if (is64)
|
||||
loadCommandsOffset += 4;
|
||||
if (is64) loadCommandsOffset += 4;
|
||||
|
||||
// Move to number of commands field.
|
||||
stream.moveTo(16);
|
||||
|
@ -2954,7 +2951,6 @@ export function extractMACHO(bytes, offset) {
|
|||
return dumpSegmentCommands(stream, loadCommandsOffset, isSwap, ncmds);
|
||||
}
|
||||
|
||||
|
||||
const stream = new Stream(bytes.slice(offset));
|
||||
const magic = stream.getBytes(4).join("");
|
||||
|
||||
|
@ -2963,7 +2959,6 @@ export function extractMACHO(bytes, offset) {
|
|||
return stream.carve();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* TAR extractor.
|
||||
*
|
||||
|
@ -2974,7 +2969,6 @@ export function extractMACHO(bytes, offset) {
|
|||
export function extractTAR(bytes, offset) {
|
||||
const stream = new Stream(bytes.slice(offset));
|
||||
while (stream.hasMore()) {
|
||||
|
||||
// Move to ustar identifier.
|
||||
stream.moveForwardsBy(0x101);
|
||||
if (stream.getBytes(5).join("") !== [0x75, 0x73, 0x74, 0x61, 0x72].join("")) {
|
||||
|
@ -2993,7 +2987,7 @@ export function extractTAR(bytes, offset) {
|
|||
});
|
||||
|
||||
// Round number up from octet to nearest 512.
|
||||
fsize = (Math.ceil(parseInt(fsize, 8) / 512) * 512);
|
||||
fsize = Math.ceil(parseInt(fsize, 8) / 512) * 512;
|
||||
|
||||
// Move forwards to the end of that file.
|
||||
stream.moveForwardsBy(fsize + 0x179);
|
||||
|
@ -3002,7 +2996,6 @@ export function extractTAR(bytes, offset) {
|
|||
return stream.carve();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* PNG extractor.
|
||||
*
|
||||
|
@ -3027,11 +3020,9 @@ export function extractPNG(bytes, offset) {
|
|||
stream.moveForwardsBy(chunkSize + 4);
|
||||
}
|
||||
|
||||
|
||||
return stream.carve();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* WEBP extractor.
|
||||
*
|
||||
|
@ -3055,7 +3046,6 @@ export function extractWEBP(bytes, offset) {
|
|||
return stream.carve();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* BMP extractor.
|
||||
*
|
||||
|
@ -3078,7 +3068,6 @@ export function extractBMP(bytes, offset) {
|
|||
return stream.carve();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* ICO extractor.
|
||||
*
|
||||
|
@ -3095,7 +3084,7 @@ export function extractICO(bytes, offset) {
|
|||
const numberFiles = stream.readInt(2, "le");
|
||||
|
||||
// Move forward to the last file header.
|
||||
stream.moveForwardsBy(8 + ((numberFiles-1) * 16));
|
||||
stream.moveForwardsBy(8 + (numberFiles - 1) * 16);
|
||||
const fileSize = stream.readInt(4, "le");
|
||||
const fileOffset = stream.readInt(4, "le");
|
||||
|
||||
|
@ -3104,7 +3093,6 @@ export function extractICO(bytes, offset) {
|
|||
return stream.carve();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* TARGA extractor.
|
||||
*
|
||||
|
@ -3137,8 +3125,7 @@ export function extractTARGA(bytes, offset) {
|
|||
stream.moveBackwardsBy(sizeOfSize);
|
||||
|
||||
// If the size matches.
|
||||
if (size === i)
|
||||
break;
|
||||
if (size === i) break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3150,11 +3137,9 @@ export function extractTARGA(bytes, offset) {
|
|||
|
||||
// The documentation said that 0x100000 was the largest the file could be.
|
||||
for (let i = 0; i < 0x100000; i++) {
|
||||
|
||||
// (Height * Width * pixel depth in bits)/8
|
||||
const total = (stream.readInt(2, "le") * stream.readInt(2, "le") * stream.readInt(1))/8;
|
||||
if (total === i-1)
|
||||
break;
|
||||
const total = (stream.readInt(2, "le") * stream.readInt(2, "le") * stream.readInt(1)) / 8;
|
||||
if (total === i - 1) break;
|
||||
|
||||
stream.moveBackwardsBy(6);
|
||||
}
|
||||
|
@ -3182,13 +3167,12 @@ export function extractTARGA(bytes, offset) {
|
|||
moveBackwardsUntilImageSize();
|
||||
|
||||
// Move backwards over the reaminder of the header + the 5 we borrowed in moveBackwardsUntilImageSize().
|
||||
stream.moveBackwardsBy(0xc+5);
|
||||
stream.moveBackwardsBy(0xc + 5);
|
||||
}
|
||||
|
||||
return stream.carve(stream.position, offset+0x12);
|
||||
return stream.carve(stream.position, offset + 0x12);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* WAV extractor.
|
||||
*
|
||||
|
@ -3208,7 +3192,6 @@ export function extractWAV(bytes, offset) {
|
|||
return stream.carve();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* MP3 extractor.
|
||||
*
|
||||
|
@ -3220,14 +3203,32 @@ export function extractMP3(bytes, offset) {
|
|||
const stream = new Stream(bytes.slice(offset));
|
||||
|
||||
// Constants for flag byte.
|
||||
const bitRateIndexes = ["free", 32000, 40000, 48000, 56000, 64000, 80000, 96000, 112000, 128000, 160000, 192000, 224000, 256000, 320000, "bad"];
|
||||
const bitRateIndexes = [
|
||||
"free",
|
||||
32000,
|
||||
40000,
|
||||
48000,
|
||||
56000,
|
||||
64000,
|
||||
80000,
|
||||
96000,
|
||||
112000,
|
||||
128000,
|
||||
160000,
|
||||
192000,
|
||||
224000,
|
||||
256000,
|
||||
320000,
|
||||
"bad"
|
||||
];
|
||||
|
||||
const samplingRateFrequencyIndex = [44100, 48000, 32000, "reserved"];
|
||||
|
||||
// ID3 tag, move over it.
|
||||
if ((stream.getBytes(3).toString() === [0x49, 0x44, 0x33].toString())) {
|
||||
if (stream.getBytes(3).toString() === [0x49, 0x44, 0x33].toString()) {
|
||||
stream.moveTo(6);
|
||||
const tagSize = (stream.readInt(1) << 21) | (stream.readInt(1) << 14) | (stream.readInt(1) << 7) | stream.readInt(1);
|
||||
const tagSize
|
||||
= (stream.readInt(1) << 21) | (stream.readInt(1) << 14) | (stream.readInt(1) << 7) | stream.readInt(1);
|
||||
stream.moveForwardsBy(tagSize);
|
||||
} else {
|
||||
stream.moveTo(0);
|
||||
|
@ -3235,7 +3236,6 @@ export function extractMP3(bytes, offset) {
|
|||
|
||||
// Loop over all the frame headers in the file.
|
||||
while (stream.hasMore()) {
|
||||
|
||||
// If it has an old TAG frame at the end of it, fixed size, 128 bytes.
|
||||
if (stream.getBytes(3) === [0x54, 0x41, 0x47].toString()) {
|
||||
stream.moveForwardsBy(125);
|
||||
|
@ -3267,11 +3267,11 @@ export function extractMP3(bytes, offset) {
|
|||
}
|
||||
|
||||
// Formula: FrameLength = (144 * BitRate / SampleRate ) + Padding
|
||||
const frameSize = Math.floor(((144 * bitRate) / sampleRate) + padding);
|
||||
const frameSize = Math.floor((144 * bitRate) / sampleRate + padding);
|
||||
|
||||
// If the next move goes past the end of the bytestream then extract the entire bytestream.
|
||||
// We assume complete frames in the above formula because there is no field that suggests otherwise.
|
||||
if ((stream.position + frameSize) > stream.length) {
|
||||
if (stream.position + frameSize > stream.length) {
|
||||
stream.moveTo(stream.length);
|
||||
break;
|
||||
} else {
|
||||
|
@ -3281,7 +3281,6 @@ export function extractMP3(bytes, offset) {
|
|||
return stream.carve();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* FLV extractor.
|
||||
*
|
||||
|
@ -3312,7 +3311,7 @@ export function extractFLV(bytes, offset) {
|
|||
break;
|
||||
}
|
||||
|
||||
if (prevTagSize !== (tagSize + 11)) {
|
||||
if (prevTagSize !== tagSize + 11) {
|
||||
// Previous tag was not valid, reverse back over this header
|
||||
// and the previous tag body and header
|
||||
stream.moveBackwardsBy(tagSize + 11 + 5);
|
||||
|
@ -3328,7 +3327,6 @@ export function extractFLV(bytes, offset) {
|
|||
return stream.carve();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* RTF extractor.
|
||||
*
|
||||
|
@ -3341,7 +3339,8 @@ export function extractRTF(bytes, offset) {
|
|||
|
||||
let openTags = 0;
|
||||
|
||||
if (stream.readInt(1) !== 0x7b) { // {
|
||||
if (stream.readInt(1) !== 0x7b) {
|
||||
// {
|
||||
throw new Error("Not a valid RTF file");
|
||||
} else {
|
||||
openTags++;
|
||||
|
@ -3368,7 +3367,6 @@ export function extractRTF(bytes, offset) {
|
|||
return stream.carve();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* SQLITE extractor.
|
||||
*
|
||||
|
@ -3388,12 +3386,11 @@ export function extractSQLITE(bytes, offset) {
|
|||
const numPages = stream.readInt(4);
|
||||
|
||||
// Move to the end of all the pages.
|
||||
stream.moveTo(pageSize*numPages);
|
||||
stream.moveTo(pageSize * numPages);
|
||||
|
||||
return stream.carve();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* PList (XML) extractor.
|
||||
*
|
||||
|
@ -3414,7 +3411,6 @@ export function extractPListXML(bytes, offset) {
|
|||
// While we have an unequal amount of braces.
|
||||
while (braceCount > 0 && stream.hasMore()) {
|
||||
if (stream.readInt(1) === 0x3c) {
|
||||
|
||||
// If we hit an <plist.
|
||||
if (stream.getBytes(5).join("") === [0x70, 0x6c, 0x69, 0x73, 0x74].join("")) {
|
||||
braceCount++;
|
||||
|
@ -3435,7 +3431,6 @@ export function extractPListXML(bytes, offset) {
|
|||
return stream.carve();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* MacOS X Keychain Extactor.
|
||||
*
|
||||
|
@ -3455,7 +3450,6 @@ export function extractMacOSXKeychain(bytes, offset) {
|
|||
return stream.carve();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* OLE2 extractor.
|
||||
*
|
||||
|
@ -3466,16 +3460,62 @@ export function extractMacOSXKeychain(bytes, offset) {
|
|||
export function extractOLE2(bytes, offset) {
|
||||
const stream = new Stream(bytes.slice(offset));
|
||||
const entries = [
|
||||
[[0x52, 0x00, 0x6f, 0x00, 0x6f, 0x00, 0x74, 0x00, 0x20, 0x00, 0x45, 0x00, 0x6e, 0x00, 0x74, 0x00, 0x72, 0x00, 0x79], 19, "Root Entry"],
|
||||
[
|
||||
[
|
||||
0x52, 0x00, 0x6f, 0x00, 0x6f, 0x00, 0x74, 0x00, 0x20, 0x00, 0x45, 0x00, 0x6e, 0x00, 0x74, 0x00, 0x72,
|
||||
0x00, 0x79
|
||||
],
|
||||
19,
|
||||
"Root Entry"
|
||||
],
|
||||
[[0x57, 0x00, 0x6f, 0x00, 0x72, 0x00, 0x6b, 0x00, 0x62, 0x00, 0x6f, 0x00, 0x6f, 0x00, 0x6b], 15, "Workbook"],
|
||||
[[0x43, 0x00, 0x75, 0x00, 0x72, 0x00, 0x72, 0x00, 0x65, 0x00, 0x6e, 0x00, 0x74, 0x00, 0x20, 0x00, 0x55, 0x00, 0x73, 0x00, 0x65, 0x00, 0x72], 23, "Current User"],
|
||||
[[0x50, 0x00, 0x6f, 0x00, 0x77, 0x00, 0x65, 0x00, 0x72, 0x00, 0x50, 0x00, 0x6f, 0x00, 0x69, 0x00, 0x6e, 0x00, 0x74, 0x00, 0x20, 0x00, 0x44, 0x00, 0x6f, 0x00, 0x63, 0x00, 0x75, 0x00, 0x6d, 0x00, 0x65, 0x00, 0x6e, 0x00, 0x74], 37, "PowerPoint Document"],
|
||||
[[0x57, 0x00, 0x6f, 0x00, 0x72, 0x00, 0x64, 0x00, 0x44, 0x00, 0x6f, 0x00, 0x63, 0x00, 0x75, 0x00, 0x6d, 0x00, 0x65, 0x00, 0x6e, 0x00, 0x74], 23, "WordDocument"],
|
||||
[
|
||||
[
|
||||
0x43, 0x00, 0x75, 0x00, 0x72, 0x00, 0x72, 0x00, 0x65, 0x00, 0x6e, 0x00, 0x74, 0x00, 0x20, 0x00, 0x55,
|
||||
0x00, 0x73, 0x00, 0x65, 0x00, 0x72
|
||||
],
|
||||
23,
|
||||
"Current User"
|
||||
],
|
||||
[
|
||||
[
|
||||
0x50, 0x00, 0x6f, 0x00, 0x77, 0x00, 0x65, 0x00, 0x72, 0x00, 0x50, 0x00, 0x6f, 0x00, 0x69, 0x00, 0x6e,
|
||||
0x00, 0x74, 0x00, 0x20, 0x00, 0x44, 0x00, 0x6f, 0x00, 0x63, 0x00, 0x75, 0x00, 0x6d, 0x00, 0x65, 0x00,
|
||||
0x6e, 0x00, 0x74
|
||||
],
|
||||
37,
|
||||
"PowerPoint Document"
|
||||
],
|
||||
[
|
||||
[
|
||||
0x57, 0x00, 0x6f, 0x00, 0x72, 0x00, 0x64, 0x00, 0x44, 0x00, 0x6f, 0x00, 0x63, 0x00, 0x75, 0x00, 0x6d,
|
||||
0x00, 0x65, 0x00, 0x6e, 0x00, 0x74
|
||||
],
|
||||
23,
|
||||
"WordDocument"
|
||||
],
|
||||
[[0x44, 0x00, 0x61, 0x00, 0x74, 0x00, 0x61], 7, "Data"],
|
||||
[[0x50, 0x00, 0x69, 0x00, 0x63, 0x00, 0x74, 0x00, 0x75, 0x00, 0x72, 0x00, 0x65, 0x00, 0x73], 15, "Pictures"],
|
||||
[[0x31, 0x00, 0x54, 0x00, 0x61, 0x00, 0x62, 0x00, 0x6c, 0x00, 0x65], 11, "1Table"],
|
||||
[[0x05, 0x00, 0x53, 0x00, 0x75, 0x00, 0x6d, 0x00, 0x6d, 0x00, 0x61, 0x00, 0x72, 0x00, 0x79, 0x00, 0x49, 0x00, 0x6e, 0x00, 0x66, 0x00, 0x6f, 0x00, 0x72, 0x00, 0x6d, 0x00, 0x61, 0x00, 0x74, 0x00, 0x69, 0x00, 0x6f, 0x00, 0x6e], 37, "SummaryInformation"],
|
||||
[[0x05, 0x00, 0x44, 0x00, 0x6f, 0x00, 0x63, 0x00, 0x75, 0x00, 0x6d, 0x00, 0x65, 0x00, 0x6e, 0x00, 0x74, 0x00, 0x53, 0x00, 0x75, 0x00, 0x6d, 0x00, 0x6d, 0x00, 0x61, 0x00, 0x72, 0x00, 0x79, 0x00, 0x49, 0x00, 0x6e, 0x00, 0x66, 0x00, 0x6f, 0x00, 0x72, 0x00, 0x6d, 0x00, 0x61, 0x00, 0x74, 0x00, 0x69, 0x00, 0x6f, 0x00, 0x6e], 53, "DocumentSummaryInformation"],
|
||||
[
|
||||
[
|
||||
0x05, 0x00, 0x53, 0x00, 0x75, 0x00, 0x6d, 0x00, 0x6d, 0x00, 0x61, 0x00, 0x72, 0x00, 0x79, 0x00, 0x49,
|
||||
0x00, 0x6e, 0x00, 0x66, 0x00, 0x6f, 0x00, 0x72, 0x00, 0x6d, 0x00, 0x61, 0x00, 0x74, 0x00, 0x69, 0x00,
|
||||
0x6f, 0x00, 0x6e
|
||||
],
|
||||
37,
|
||||
"SummaryInformation"
|
||||
],
|
||||
[
|
||||
[
|
||||
0x05, 0x00, 0x44, 0x00, 0x6f, 0x00, 0x63, 0x00, 0x75, 0x00, 0x6d, 0x00, 0x65, 0x00, 0x6e, 0x00, 0x74,
|
||||
0x00, 0x53, 0x00, 0x75, 0x00, 0x6d, 0x00, 0x6d, 0x00, 0x61, 0x00, 0x72, 0x00, 0x79, 0x00, 0x49, 0x00,
|
||||
0x6e, 0x00, 0x66, 0x00, 0x6f, 0x00, 0x72, 0x00, 0x6d, 0x00, 0x61, 0x00, 0x74, 0x00, 0x69, 0x00, 0x6f,
|
||||
0x00, 0x6e
|
||||
],
|
||||
53,
|
||||
"DocumentSummaryInformation"
|
||||
],
|
||||
[[0x43, 0x00, 0x6f, 0x00, 0x6d, 0x00, 0x70, 0x00, 0x4f, 0x00, 0x62, 0x00, 0x6a], 13, "Comp Obj"],
|
||||
[[0x01, 0x00], 2, "Entry"]
|
||||
];
|
||||
|
@ -3483,8 +3523,7 @@ export function extractOLE2(bytes, offset) {
|
|||
|
||||
// Move to endianess field.
|
||||
stream.moveForwardsBy(28);
|
||||
if (stream.readInt(2, endianness) === 0xfffe)
|
||||
endianness = "be";
|
||||
if (stream.readInt(2, endianness) === 0xfffe) endianness = "be";
|
||||
|
||||
// Calculate the size of the normal sectors.
|
||||
const sizeOfSector = 2 ** stream.readInt(2, endianness);
|
||||
|
@ -3493,10 +3532,10 @@ export function extractOLE2(bytes, offset) {
|
|||
stream.moveTo(48);
|
||||
|
||||
// Read root directory offset.
|
||||
const rootStuff = stream.readInt(4, endianness);
|
||||
const rootStuff = stream.readInt(4, endianness);
|
||||
|
||||
// Calculate root directory offset.
|
||||
let total = 512 + (rootStuff * sizeOfSector);
|
||||
let total = 512 + rootStuff * sizeOfSector;
|
||||
stream.moveTo(total);
|
||||
|
||||
// While valid directory entries.
|
||||
|
@ -3506,7 +3545,6 @@ export function extractOLE2(bytes, offset) {
|
|||
|
||||
// Attempt to determine what directory entry it is.
|
||||
for (const element of entries) {
|
||||
|
||||
// If the byte pattern matches.
|
||||
if (stream.getBytes(element[1]).join("") === element[0].join("")) {
|
||||
stream.moveBackwardsBy(element[1]);
|
||||
|
@ -3514,12 +3552,10 @@ export function extractOLE2(bytes, offset) {
|
|||
|
||||
// Move forwards by the size of the comp obj.
|
||||
if (element[2] === "Comp Obj") {
|
||||
|
||||
// The size of the Comp Obj entry - 128. Since we add 128 later.
|
||||
total += 128 * 6;
|
||||
stream.moveTo(total);
|
||||
} else if (element[2] === "Entry") {
|
||||
|
||||
// If there is an entry move backwards by 126 to then move forwards by 128. Hence a total displacement of 2.
|
||||
stream.moveBackwardsBy(126);
|
||||
}
|
||||
|
@ -3530,7 +3566,6 @@ export function extractOLE2(bytes, offset) {
|
|||
|
||||
// If we have found a valid entry, move forwards by 128.
|
||||
if (found) {
|
||||
|
||||
// Every entry is at least 128 in size, some are bigger which is dealt with by the above if statement.
|
||||
total += 128;
|
||||
stream.moveForwardsBy(128);
|
||||
|
@ -3544,7 +3579,6 @@ export function extractOLE2(bytes, offset) {
|
|||
return stream.carve();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* GZIP extractor.
|
||||
*
|
||||
|
@ -3555,7 +3589,6 @@ export function extractOLE2(bytes, offset) {
|
|||
export function extractGZIP(bytes, offset) {
|
||||
const stream = new Stream(bytes.slice(offset));
|
||||
|
||||
|
||||
/* HEADER */
|
||||
|
||||
// Skip over signature and compression method
|
||||
|
@ -3573,7 +3606,6 @@ export function extractGZIP(bytes, offset) {
|
|||
// Skip over OS
|
||||
stream.moveForwardsBy(1);
|
||||
|
||||
|
||||
/* OPTIONAL HEADERS */
|
||||
|
||||
// Extra fields
|
||||
|
@ -3599,12 +3631,10 @@ export function extractGZIP(bytes, offset) {
|
|||
stream.moveForwardsBy(2);
|
||||
}
|
||||
|
||||
|
||||
/* DEFLATE DATA */
|
||||
|
||||
parseDEFLATE(stream);
|
||||
|
||||
|
||||
/* FOOTER */
|
||||
|
||||
// Skip over checksum and size of original uncompressed input
|
||||
|
@ -3613,7 +3643,6 @@ export function extractGZIP(bytes, offset) {
|
|||
return stream.carve();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* BZIP2 extractor.
|
||||
*
|
||||
|
@ -3640,8 +3669,7 @@ export function extractBZIP2(bytes, offset) {
|
|||
for (let i = 0; i < lookingfor.length; i++) {
|
||||
// Continue until an EOF.
|
||||
stream.continueUntil(lookingfor[i]);
|
||||
if (stream.getBytes(5).join("") === lookingfor[i].join(""))
|
||||
break;
|
||||
if (stream.getBytes(5).join("") === lookingfor[i].join("")) break;
|
||||
|
||||
// Jump back to the start if invalid EOF.
|
||||
stream.moveTo(0);
|
||||
|
@ -3650,7 +3678,6 @@ export function extractBZIP2(bytes, offset) {
|
|||
return stream.carve();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Zlib extractor.
|
||||
*
|
||||
|
@ -3681,7 +3708,6 @@ export function extractZlib(bytes, offset) {
|
|||
return stream.carve();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* XZ extractor.
|
||||
*
|
||||
|
@ -3701,7 +3727,6 @@ export function extractXZ(bytes, offset) {
|
|||
return stream.carve();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* DEB extractor.
|
||||
*
|
||||
|
@ -3714,10 +3739,9 @@ export function extractDEB(bytes, offset) {
|
|||
// Move past !<arch>
|
||||
stream.moveForwardsBy(8);
|
||||
while (stream.hasMore()) {
|
||||
|
||||
// Move to size field.
|
||||
stream.moveForwardsBy(48);
|
||||
let fsize= "";
|
||||
let fsize = "";
|
||||
|
||||
// Convert size to a usable number.
|
||||
for (const elem of stream.getBytes(10)) {
|
||||
|
@ -3732,7 +3756,6 @@ export function extractDEB(bytes, offset) {
|
|||
return stream.carve();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* ELF extractor.
|
||||
*
|
||||
|
@ -3776,15 +3799,10 @@ export function extractELF(bytes, offset) {
|
|||
return stream.carve();
|
||||
}
|
||||
|
||||
|
||||
// Construct required Huffman Tables
|
||||
const fixedLiteralTableLengths = new Array(288);
|
||||
for (let i = 0; i < fixedLiteralTableLengths.length; i++) {
|
||||
fixedLiteralTableLengths[i] =
|
||||
(i <= 143) ? 8 :
|
||||
(i <= 255) ? 9 :
|
||||
(i <= 279) ? 7 :
|
||||
8;
|
||||
fixedLiteralTableLengths[i] = i <= 143 ? 8 : i <= 255 ? 9 : i <= 279 ? 7 : 8;
|
||||
}
|
||||
const fixedLiteralTable = buildHuffmanTable(fixedLiteralTableLengths);
|
||||
const fixedDistanceTableLengths = new Array(30).fill(5);
|
||||
|
@ -3873,15 +3891,11 @@ function parseDEFLATE(stream) {
|
|||
}
|
||||
|
||||
// Consume final byte if it has not been fully consumed yet
|
||||
if (stream.bitPos > 0)
|
||||
stream.moveForwardsBy(1);
|
||||
if (stream.bitPos > 0) stream.moveForwardsBy(1);
|
||||
}
|
||||
|
||||
|
||||
// Static length tables
|
||||
const lengthExtraTable = [
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 0, 0
|
||||
];
|
||||
const lengthExtraTable = [0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 0, 0];
|
||||
const distanceExtraTable = [
|
||||
0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13
|
||||
];
|
||||
|
@ -3903,8 +3917,7 @@ function parseHuffmanBlock(stream, litTab, distTab) {
|
|||
if (code === 256) break;
|
||||
|
||||
// Detect probably infinite loops
|
||||
if (++loops > 10000)
|
||||
throw new Error("Caught in probable infinite loop while parsing Huffman Block");
|
||||
if (++loops > 10000) throw new Error("Caught in probable infinite loop while parsing Huffman Block");
|
||||
|
||||
// Literal
|
||||
if (code < 256) continue;
|
||||
|
@ -3918,7 +3931,6 @@ function parseHuffmanBlock(stream, litTab, distTab) {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Builds a Huffman table given the relevant code lengths
|
||||
*
|
||||
|
@ -3960,7 +3972,6 @@ function buildHuffmanTable(lengths) {
|
|||
return [table, maxCodeLength, minCodeLength];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Reads the next Huffman code from the stream, given the relevant code table
|
||||
*
|
||||
|
@ -3977,7 +3988,9 @@ function readHuffmanCode(stream, table) {
|
|||
const codeLength = codeWithLength >>> 16;
|
||||
|
||||
if (codeLength > maxCodeLength) {
|
||||
throw new Error(`Invalid Huffman Code length while parsing DEFLATE block at pos ${stream.position}: ${codeLength}`);
|
||||
throw new Error(
|
||||
`Invalid Huffman Code length while parsing DEFLATE block at pos ${stream.position}: ${codeLength}`
|
||||
);
|
||||
}
|
||||
|
||||
stream.moveBackwardsByBits(maxCodeLength - codeLength);
|
||||
|
@ -3985,7 +3998,6 @@ function readHuffmanCode(stream, table) {
|
|||
return codeWithLength & 0xffff;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* EVTX extractor.
|
||||
*
|
||||
|
@ -4003,15 +4015,13 @@ export function extractEVTX(bytes, offset) {
|
|||
|
||||
while (stream.hasMore()) {
|
||||
// Loop through ELFCHNKs.
|
||||
if (stream.getBytes(7).join("") !== [0x45, 0x6c, 0x66, 0x43, 0x68, 0x6e, 0x6b].join(""))
|
||||
break;
|
||||
if (stream.getBytes(7).join("") !== [0x45, 0x6c, 0x66, 0x43, 0x68, 0x6e, 0x6b].join("")) break;
|
||||
stream.moveForwardsBy(0xfff9);
|
||||
}
|
||||
stream.consumeWhile(0x00);
|
||||
return stream.carve();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* EVT extractor.
|
||||
*
|
||||
|
@ -4031,11 +4041,10 @@ export function extractEVT(bytes, offset) {
|
|||
const eofSize = stream.readInt(4, "le");
|
||||
|
||||
// Move past EOF.
|
||||
stream.moveForwardsBy(eofSize-4);
|
||||
stream.moveForwardsBy(eofSize - 4);
|
||||
return stream.carve();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* DMP extractor.
|
||||
*
|
||||
|
@ -4055,7 +4064,6 @@ export function extractDMP(bytes, offset) {
|
|||
return stream.carve();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* PF extractor.
|
||||
*
|
||||
|
@ -4073,7 +4081,6 @@ export function extractPF(bytes, offset) {
|
|||
return stream.carve();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* PF (Win 10) extractor.
|
||||
*
|
||||
|
@ -4090,7 +4097,6 @@ export function extractPFWin10(bytes, offset) {
|
|||
return stream.carve();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* LNK extractor.
|
||||
*
|
||||
|
@ -4108,7 +4114,6 @@ export function extractLNK(bytes, offset) {
|
|||
return stream.carve();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* LZOP extractor.
|
||||
*
|
||||
|
@ -4127,7 +4132,8 @@ export function extractLZOP(bytes, offset) {
|
|||
const F_H_FILTER = 0x00000800;
|
||||
const F_H_EXTRA_FIELD = 0x00000040;
|
||||
|
||||
let numCheckSumC = 0, numCheckSumD = 0;
|
||||
let numCheckSumC = 0,
|
||||
numCheckSumD = 0;
|
||||
|
||||
// Move over magic bytes.
|
||||
stream.moveForwardsBy(9);
|
||||
|
@ -4138,26 +4144,20 @@ export function extractLZOP(bytes, offset) {
|
|||
stream.moveForwardsBy(6);
|
||||
const flags = stream.readInt(4, "be");
|
||||
|
||||
if (version & F_H_FILTER)
|
||||
stream.moveForwardsBy(4);
|
||||
if (version & F_H_FILTER) stream.moveForwardsBy(4);
|
||||
|
||||
if (flags & F_ADLER32_C)
|
||||
numCheckSumC++;
|
||||
if (flags & F_ADLER32_C) numCheckSumC++;
|
||||
|
||||
if (flags & F_CRC32_C)
|
||||
numCheckSumC++;
|
||||
if (flags & F_CRC32_C) numCheckSumC++;
|
||||
|
||||
if (flags & F_ADLER32_D)
|
||||
numCheckSumD++;
|
||||
if (flags & F_ADLER32_D) numCheckSumD++;
|
||||
|
||||
if (flags & F_CRC32_D)
|
||||
numCheckSumD++;
|
||||
if (flags & F_CRC32_D) numCheckSumD++;
|
||||
|
||||
// Move over the mode, mtime_low
|
||||
stream.moveForwardsBy(8);
|
||||
|
||||
if (version >= 0x0940)
|
||||
stream.moveForwardsBy(4);
|
||||
if (version >= 0x0940) stream.moveForwardsBy(4);
|
||||
|
||||
const fnameSize = stream.readInt(1, "be");
|
||||
|
||||
|
@ -4176,16 +4176,14 @@ export function extractLZOP(bytes, offset) {
|
|||
const uncompSize = stream.readInt(4, "be");
|
||||
|
||||
// If data has no length, break.
|
||||
if (uncompSize === 0)
|
||||
break;
|
||||
if (uncompSize === 0) break;
|
||||
|
||||
const compSize = stream.readInt(4, "be");
|
||||
|
||||
const numCheckSumSkip = (uncompSize === compSize) ? numCheckSumD : numCheckSumD + numCheckSumC;
|
||||
const numCheckSumSkip = uncompSize === compSize ? numCheckSumD : numCheckSumD + numCheckSumC;
|
||||
|
||||
// skip forwards by compressed data size and the size of the checksum(s).
|
||||
stream.moveForwardsBy(compSize + (numCheckSumSkip * 4));
|
||||
stream.moveForwardsBy(compSize + numCheckSumSkip * 4);
|
||||
}
|
||||
return stream.carve();
|
||||
|
||||
}
|
||||
|
|
|
@ -6,9 +6,8 @@
|
|||
* @license Apache-2.0
|
||||
*
|
||||
*/
|
||||
import {FILE_SIGNATURES} from "./FileSignatures.mjs";
|
||||
import {sendStatusMessage} from "../Utils.mjs";
|
||||
|
||||
import { FILE_SIGNATURES } from "./FileSignatures.mjs";
|
||||
import { sendStatusMessage } from "../Utils.mjs";
|
||||
|
||||
/**
|
||||
* Checks whether a signature matches a buffer.
|
||||
|
@ -20,7 +19,7 @@ import {sendStatusMessage} from "../Utils.mjs";
|
|||
* @param {number} [offset=0] Where in the buffer to start searching from
|
||||
* @returns {boolean}
|
||||
*/
|
||||
function signatureMatches(sig, buf, offset=0) {
|
||||
function signatureMatches(sig, buf, offset = 0) {
|
||||
// Using a length check seems to be more performant than `sig instanceof Array`
|
||||
if (sig.length) {
|
||||
// sig is an Array - return true if any of them match
|
||||
|
@ -36,7 +35,6 @@ function signatureMatches(sig, buf, offset=0) {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Checks whether a set of bytes match the given buffer.
|
||||
*
|
||||
|
@ -47,21 +45,18 @@ function signatureMatches(sig, buf, offset=0) {
|
|||
* @param {number} [offset=0] Where in the buffer to start searching from
|
||||
* @returns {boolean}
|
||||
*/
|
||||
function bytesMatch(sig, buf, offset=0) {
|
||||
function bytesMatch(sig, buf, offset = 0) {
|
||||
for (const sigoffset in sig) {
|
||||
const pos = parseInt(sigoffset, 10) + offset;
|
||||
switch (typeof sig[sigoffset]) {
|
||||
case "number": // Static check
|
||||
if (buf[pos] !== sig[sigoffset])
|
||||
return false;
|
||||
if (buf[pos] !== sig[sigoffset]) return false;
|
||||
break;
|
||||
case "object": // Array of options
|
||||
if (sig[sigoffset].indexOf(buf[pos]) < 0)
|
||||
return false;
|
||||
if (sig[sigoffset].indexOf(buf[pos]) < 0) return false;
|
||||
break;
|
||||
case "function": // More complex calculation
|
||||
if (!sig[sigoffset](buf[pos]))
|
||||
return false;
|
||||
if (!sig[sigoffset](buf[pos])) return false;
|
||||
break;
|
||||
default:
|
||||
throw new Error(`Unrecognised signature type at offset ${sigoffset}`);
|
||||
|
@ -70,7 +65,6 @@ function bytesMatch(sig, buf, offset=0) {
|
|||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Given a buffer, detects magic byte sequences at specific positions and returns the
|
||||
* extension and mime type.
|
||||
|
@ -83,7 +77,7 @@ function bytesMatch(sig, buf, offset=0) {
|
|||
* @returns {string} type.mime - Mime type
|
||||
* @returns {string} [type.desc] - Description
|
||||
*/
|
||||
export function detectFileType(buf, categories=Object.keys(FILE_SIGNATURES)) {
|
||||
export function detectFileType(buf, categories = Object.keys(FILE_SIGNATURES)) {
|
||||
if (buf instanceof ArrayBuffer) {
|
||||
buf = new Uint8Array(buf);
|
||||
}
|
||||
|
@ -104,7 +98,7 @@ export function detectFileType(buf, categories=Object.keys(FILE_SIGNATURES)) {
|
|||
for (const cat in signatures) {
|
||||
const category = signatures[cat];
|
||||
|
||||
category.forEach(filetype => {
|
||||
category.forEach((filetype) => {
|
||||
if (signatureMatches(filetype.signature, buf)) {
|
||||
matchingFiles.push(filetype);
|
||||
}
|
||||
|
@ -113,7 +107,6 @@ export function detectFileType(buf, categories=Object.keys(FILE_SIGNATURES)) {
|
|||
return matchingFiles;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Given a buffer, searches for magic byte sequences at all possible positions and returns
|
||||
* the extensions and mime types.
|
||||
|
@ -128,7 +121,7 @@ export function detectFileType(buf, categories=Object.keys(FILE_SIGNATURES)) {
|
|||
* @returns {string} foundFiles.fileDetails.mime - Mime type
|
||||
* @returns {string} [foundFiles.fileDetails.desc] - Description
|
||||
*/
|
||||
export function scanForFileTypes(buf, categories=Object.keys(FILE_SIGNATURES)) {
|
||||
export function scanForFileTypes(buf, categories = Object.keys(FILE_SIGNATURES)) {
|
||||
if (!(buf && buf.length > 1)) {
|
||||
return [];
|
||||
}
|
||||
|
@ -149,7 +142,7 @@ export function scanForFileTypes(buf, categories=Object.keys(FILE_SIGNATURES)) {
|
|||
const filetype = category[i];
|
||||
const sigs = filetype.signature.length ? filetype.signature : [filetype.signature];
|
||||
|
||||
sigs.forEach(sig => {
|
||||
sigs.forEach((sig) => {
|
||||
let pos = 0;
|
||||
while ((pos = locatePotentialSig(buf, sig, pos)) >= 0) {
|
||||
if (bytesMatch(sig, buf, pos)) {
|
||||
|
@ -171,7 +164,6 @@ export function scanForFileTypes(buf, categories=Object.keys(FILE_SIGNATURES)) {
|
|||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Fastcheck function to quickly scan the buffer for the first byte in a signature.
|
||||
*
|
||||
|
@ -202,7 +194,6 @@ function locatePotentialSig(buf, sig, offset) {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Detects whether the given buffer is a file of the type specified.
|
||||
*
|
||||
|
@ -230,7 +221,6 @@ export function isType(type, buf) {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Detects whether the given buffer contains an image file.
|
||||
*
|
||||
|
@ -241,7 +231,6 @@ export function isImage(buf) {
|
|||
return isType("image", buf);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Attempts to extract a file from a data stream given its offset and extractor function.
|
||||
*
|
||||
|
|
|
@ -15,6 +15,6 @@
|
|||
*/
|
||||
export function getLabelIndex(name, state) {
|
||||
return state.opList.findIndex((operation) => {
|
||||
return (operation.name === "Label") && (name === operation.ingValues[0]);
|
||||
return operation.name === "Label" && name === operation.ingValues[0];
|
||||
});
|
||||
}
|
||||
|
|
|
@ -35,7 +35,7 @@ export const DEFAULT_WEIGHTS = {
|
|||
* @returns [boolean, number] a boolean which tells if pattern was
|
||||
* found or not and a search score
|
||||
*/
|
||||
export function fuzzyMatch(pattern, str, global=false, weights=DEFAULT_WEIGHTS) {
|
||||
export function fuzzyMatch(pattern, str, global = false, weights = DEFAULT_WEIGHTS) {
|
||||
const recursionCount = 0;
|
||||
const recursionLimit = 10;
|
||||
const matches = [];
|
||||
|
@ -121,9 +121,7 @@ function fuzzyMatchRecursive(
|
|||
let firstMatch = true;
|
||||
while (patternCurIndex < pattern.length && strCurrIndex < str.length) {
|
||||
// Match found.
|
||||
if (
|
||||
pattern[patternCurIndex].toLowerCase() === str[strCurrIndex].toLowerCase()
|
||||
) {
|
||||
if (pattern[patternCurIndex].toLowerCase() === str[strCurrIndex].toLowerCase()) {
|
||||
if (nextMatch >= maxMatches) {
|
||||
return [false, outScore, []];
|
||||
}
|
||||
|
@ -169,10 +167,7 @@ function fuzzyMatchRecursive(
|
|||
|
||||
// Apply leading letter penalty
|
||||
let penalty = weights.leadingLetterPenalty * matches[0];
|
||||
penalty =
|
||||
penalty < weights.maxLeadingLetterPenalty ?
|
||||
weights.maxLeadingLetterPenalty :
|
||||
penalty;
|
||||
penalty = penalty < weights.maxLeadingLetterPenalty ? weights.maxLeadingLetterPenalty : penalty;
|
||||
outScore += penalty;
|
||||
|
||||
// Apply unmatched penalty
|
||||
|
@ -195,10 +190,7 @@ function fuzzyMatchRecursive(
|
|||
// Camel case
|
||||
const neighbor = str[currIdx - 1];
|
||||
const curr = str[currIdx];
|
||||
if (
|
||||
neighbor !== neighbor.toUpperCase() &&
|
||||
curr !== curr.toLowerCase()
|
||||
) {
|
||||
if (neighbor !== neighbor.toUpperCase() && curr !== curr.toLowerCase()) {
|
||||
outScore += weights.camelBonus;
|
||||
}
|
||||
const isNeighbourSeparator = neighbor === "_" || neighbor === " ";
|
||||
|
@ -239,7 +231,7 @@ export function calcMatchRanges(matches) {
|
|||
let start = matches[0],
|
||||
curr = start;
|
||||
|
||||
matches.forEach(m => {
|
||||
matches.forEach((m) => {
|
||||
if (m === curr || m === curr + 1) curr = m;
|
||||
else {
|
||||
ranges.push([start, curr - start + 1]);
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
import Utils from "../Utils.mjs";
|
||||
import CryptoApi from "crypto-api/src/crypto-api.mjs";
|
||||
|
||||
|
||||
/**
|
||||
* Generic hash function.
|
||||
*
|
||||
|
@ -19,10 +18,9 @@ import CryptoApi from "crypto-api/src/crypto-api.mjs";
|
|||
* @param {Object} [options={}]
|
||||
* @returns {string}
|
||||
*/
|
||||
export function runHash(name, input, options={}) {
|
||||
export function runHash(name, input, options = {}) {
|
||||
const msg = Utils.arrayBufferToStr(input, false),
|
||||
hasher = CryptoApi.getHasher(name, options);
|
||||
hasher.update(msg);
|
||||
return CryptoApi.encoder.toHex(hasher.finalize());
|
||||
}
|
||||
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
import Utils from "../Utils.mjs";
|
||||
import OperationError from "../errors/OperationError.mjs";
|
||||
|
||||
|
||||
/**
|
||||
* Convert a byte array into a hex string.
|
||||
*
|
||||
|
@ -28,12 +27,12 @@ import OperationError from "../errors/OperationError.mjs";
|
|||
* // returns "0x0a,0x14,0x1e"
|
||||
* toHex([10,20,30], "0x", 2, ",")
|
||||
*/
|
||||
export function toHex(data, delim=" ", padding=2, extraDelim="", lineSize=0) {
|
||||
export function toHex(data, delim = " ", padding = 2, extraDelim = "", lineSize = 0) {
|
||||
if (!data) return "";
|
||||
if (data instanceof ArrayBuffer) data = new Uint8Array(data);
|
||||
|
||||
let output = "";
|
||||
const prepend = (delim === "0x" || delim === "\\x");
|
||||
const prepend = delim === "0x" || delim === "\\x";
|
||||
|
||||
for (let i = 0; i < data.length; i++) {
|
||||
const hex = data[i].toString(16).padStart(padding, "0");
|
||||
|
@ -43,7 +42,7 @@ export function toHex(data, delim=" ", padding=2, extraDelim="", lineSize=0) {
|
|||
output += extraDelim;
|
||||
}
|
||||
// Add LF after each lineSize amount of bytes but not at the end
|
||||
if ((i !== data.length - 1) && ((i + 1) % lineSize === 0)) {
|
||||
if (i !== data.length - 1 && (i + 1) % lineSize === 0) {
|
||||
output += "\n";
|
||||
}
|
||||
}
|
||||
|
@ -59,7 +58,6 @@ export function toHex(data, delim=" ", padding=2, extraDelim="", lineSize=0) {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Convert a byte array into a hex string as efficiently as possible with no options.
|
||||
*
|
||||
|
@ -84,7 +82,6 @@ export function toHexFast(data) {
|
|||
return output.join("");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Convert a hex string into a byte array.
|
||||
*
|
||||
|
@ -100,7 +97,7 @@ export function toHexFast(data) {
|
|||
* // returns [10,20,30]
|
||||
* fromHex("0a:14:1e", "Colon");
|
||||
*/
|
||||
export function fromHex(data, delim="Auto", byteLen=2) {
|
||||
export function fromHex(data, delim = "Auto", byteLen = 2) {
|
||||
if (byteLen < 1 || Math.round(byteLen) !== byteLen)
|
||||
throw new OperationError("Byte length must be a positive integer");
|
||||
|
||||
|
@ -120,12 +117,22 @@ export function fromHex(data, delim="Auto", byteLen=2) {
|
|||
return output;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* To Hexadecimal delimiters.
|
||||
*/
|
||||
export const TO_HEX_DELIM_OPTIONS = ["Space", "Percent", "Comma", "Semi-colon", "Colon", "Line feed", "CRLF", "0x", "0x with comma", "\\x", "None"];
|
||||
|
||||
export const TO_HEX_DELIM_OPTIONS = [
|
||||
"Space",
|
||||
"Percent",
|
||||
"Comma",
|
||||
"Semi-colon",
|
||||
"Colon",
|
||||
"Line feed",
|
||||
"CRLF",
|
||||
"0x",
|
||||
"0x with comma",
|
||||
"\\x",
|
||||
"None"
|
||||
];
|
||||
|
||||
/**
|
||||
* From Hexadecimal delimiters.
|
||||
|
|
|
@ -29,7 +29,7 @@ export function ipv4CidrRange(cidr, includeNetworkInfo, enumerateAddresses, allo
|
|||
throw new OperationError("IPv4 CIDR must be less than 32");
|
||||
}
|
||||
|
||||
const mask = ~(0xFFFFFFFF >>> cidrRange),
|
||||
const mask = ~(0xffffffff >>> cidrRange),
|
||||
ip1 = network & mask,
|
||||
ip2 = ip1 | ~mask;
|
||||
|
||||
|
@ -61,7 +61,7 @@ export function ipv4CidrRange(cidr, includeNetworkInfo, enumerateAddresses, allo
|
|||
export function ipv6CidrRange(cidr, includeNetworkInfo) {
|
||||
let output = "";
|
||||
const network = strToIpv6(cidr[1]),
|
||||
cidrRange = parseInt(cidr[cidr.length-1], 10);
|
||||
cidrRange = parseInt(cidr[cidr.length - 1], 10);
|
||||
|
||||
if (cidrRange < 0 || cidrRange > 127) {
|
||||
throw new OperationError("IPv6 CIDR must be less than 128");
|
||||
|
@ -74,15 +74,14 @@ export function ipv6CidrRange(cidr, includeNetworkInfo) {
|
|||
const mask = genIpv6Mask(cidrRange);
|
||||
let totalDiff = "";
|
||||
|
||||
|
||||
for (let i = 0; i < 8; i++) {
|
||||
ip1[i] = network[i] & mask[i];
|
||||
ip2[i] = ip1[i] | (~mask[i] & 0x0000FFFF);
|
||||
ip2[i] = ip1[i] | (~mask[i] & 0x0000ffff);
|
||||
totalDiff = (ip2[i] - ip1[i]).toString(2);
|
||||
|
||||
if (totalDiff !== "0") {
|
||||
for (let n = 0; n < totalDiff.length; n++) {
|
||||
total[i*16 + 16-(totalDiff.length-n)] = totalDiff[n];
|
||||
total[i * 16 + 16 - (totalDiff.length - n)] = totalDiff[n];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -137,16 +136,16 @@ export function ipv4HyphenatedRange(range, includeNetworkInfo, enumerateAddresse
|
|||
\tCIDR: ${cidr}
|
||||
\tMask: ${ipv4ToStr(mask)}
|
||||
\tSubnet range: ${ipv4ToStr(subIp1)} - ${ipv4ToStr(subIp2)}
|
||||
\tTotal addresses in subnet: ${(((subIp2 - subIp1) >>> 0) + 1)}
|
||||
\tTotal addresses in subnet: ${((subIp2 - subIp1) >>> 0) + 1}
|
||||
|
||||
Range: ${ipv4ToStr(ip1)} - ${ipv4ToStr(ip2)}
|
||||
Total addresses in range: ${(((ip2 - ip1) >>> 0) + 1)}
|
||||
Total addresses in range: ${((ip2 - ip1) >>> 0) + 1}
|
||||
|
||||
`;
|
||||
}
|
||||
|
||||
if (enumerateAddresses) {
|
||||
if (((ip2 - ip1) >>> 0) <= 65536 || allowLargeList) {
|
||||
if ((ip2 - ip1) >>> 0 <= 65536 || allowLargeList) {
|
||||
output += generateIpv4Range(ip1, ip2).join("\n");
|
||||
} else {
|
||||
output += _LARGE_RANGE_ERROR;
|
||||
|
@ -175,7 +174,7 @@ export function ipv6HyphenatedRange(range, includeNetworkInfo) {
|
|||
t = (ip2[i] - ip1[i]).toString(2);
|
||||
if (t !== "0") {
|
||||
for (let n = 0; n < t.length; n++) {
|
||||
total[i*16 + 16-(t.length-n)] = t[n];
|
||||
total[i * 16 + 16 - (t.length - n)] = t[n];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -200,11 +199,10 @@ export function ipv6HyphenatedRange(range, includeNetworkInfo) {
|
|||
* @returns {string}
|
||||
*/
|
||||
export function ipv4ListedRange(match, includeNetworkInfo, enumerateAddresses, allowLargeList) {
|
||||
|
||||
let ipv4List = match[0].split("\n");
|
||||
ipv4List = ipv4List.filter(Boolean);
|
||||
|
||||
const ipv4CidrList = ipv4List.filter(function(a) {
|
||||
const ipv4CidrList = ipv4List.filter(function (a) {
|
||||
return a.includes("/");
|
||||
});
|
||||
for (let i = 0; i < ipv4CidrList.length; i++) {
|
||||
|
@ -213,7 +211,7 @@ export function ipv4ListedRange(match, includeNetworkInfo, enumerateAddresses, a
|
|||
if (cidrRange < 0 || cidrRange > 31) {
|
||||
throw new OperationError("IPv4 CIDR must be less than 32");
|
||||
}
|
||||
const mask = ~(0xFFFFFFFF >>> cidrRange),
|
||||
const mask = ~(0xffffffff >>> cidrRange),
|
||||
cidrIp1 = network & mask,
|
||||
cidrIp2 = cidrIp1 | ~mask;
|
||||
ipv4List.splice(ipv4List.indexOf(ipv4CidrList[i]), 1);
|
||||
|
@ -236,20 +234,18 @@ export function ipv4ListedRange(match, includeNetworkInfo, enumerateAddresses, a
|
|||
* @returns {string}
|
||||
*/
|
||||
export function ipv6ListedRange(match, includeNetworkInfo) {
|
||||
|
||||
let ipv6List = match[0].split("\n");
|
||||
ipv6List = ipv6List.filter(function(str) {
|
||||
ipv6List = ipv6List.filter(function (str) {
|
||||
return str.trim();
|
||||
});
|
||||
for (let i =0; i < ipv6List.length; i++) {
|
||||
for (let i = 0; i < ipv6List.length; i++) {
|
||||
ipv6List[i] = ipv6List[i].trim();
|
||||
}
|
||||
const ipv6CidrList = ipv6List.filter(function(a) {
|
||||
const ipv6CidrList = ipv6List.filter(function (a) {
|
||||
return a.includes("/");
|
||||
});
|
||||
|
||||
for (let i = 0; i < ipv6CidrList.length; i++) {
|
||||
|
||||
const network = strToIpv6(ipv6CidrList[i].split("/")[0]);
|
||||
const cidrRange = parseInt(ipv6CidrList[i].split("/")[1], 10);
|
||||
|
||||
|
@ -264,7 +260,7 @@ export function ipv6ListedRange(match, includeNetworkInfo) {
|
|||
|
||||
for (let j = 0; j < 8; j++) {
|
||||
cidrIp1[j] = network[j] & mask[j];
|
||||
cidrIp2[j] = cidrIp1[j] | (~mask[j] & 0x0000FFFF);
|
||||
cidrIp2[j] = cidrIp1[j] | (~mask[j] & 0x0000ffff);
|
||||
}
|
||||
ipv6List.splice(ipv6List.indexOf(ipv6CidrList[i]), 1);
|
||||
ipv6List.push(ipv6ToStr(cidrIp1), ipv6ToStr(cidrIp2));
|
||||
|
@ -302,14 +298,12 @@ export function strToIpv4(ipStr) {
|
|||
* Converts a list of 4 numeric strings in the range 0-255 to a list of numbers.
|
||||
*/
|
||||
function parseBlocks(blocks) {
|
||||
if (blocks.length !== 4)
|
||||
throw new OperationError("More than 4 blocks.");
|
||||
if (blocks.length !== 4) throw new OperationError("More than 4 blocks.");
|
||||
|
||||
const numBlocks = [];
|
||||
for (let i = 0; i < 4; i++) {
|
||||
numBlocks[i] = parseInt(blocks[i], 10);
|
||||
if (numBlocks[i] < 0 || numBlocks[i] > 255)
|
||||
throw new OperationError("Block out of range.");
|
||||
if (numBlocks[i] < 0 || numBlocks[i] > 255) throw new OperationError("Block out of range.");
|
||||
}
|
||||
return numBlocks;
|
||||
}
|
||||
|
@ -334,7 +328,6 @@ export function ipv4ToStr(ipInt) {
|
|||
return blockA + "." + blockB + "." + blockC + "." + blockD;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Converts an IPv6 address from string format to numerical array format.
|
||||
*
|
||||
|
@ -354,7 +347,7 @@ export function strToIpv6(ipStr) {
|
|||
for (let i = 0; i < 8; i++) {
|
||||
if (isNaN(numBlocks[j])) {
|
||||
ipv6[i] = 0;
|
||||
if (i === (8-numBlocks.slice(j).length)) j++;
|
||||
if (i === 8 - numBlocks.slice(j).length) j++;
|
||||
} else {
|
||||
ipv6[i] = numBlocks[j];
|
||||
j++;
|
||||
|
@ -366,13 +359,11 @@ export function strToIpv6(ipStr) {
|
|||
* Converts a list of 3-8 numeric hex strings in the range 0-65535 to a list of numbers.
|
||||
*/
|
||||
function parseBlocks(blocks) {
|
||||
if (blocks.length < 3 || blocks.length > 8)
|
||||
throw new OperationError("Badly formatted IPv6 address.");
|
||||
if (blocks.length < 3 || blocks.length > 8) throw new OperationError("Badly formatted IPv6 address.");
|
||||
const numBlocks = [];
|
||||
for (let i = 0; i < blocks.length; i++) {
|
||||
numBlocks[i] = parseInt(blocks[i], 16);
|
||||
if (numBlocks[i] < 0 || numBlocks[i] > 65535)
|
||||
throw new OperationError("Block out of range.");
|
||||
if (numBlocks[i] < 0 || numBlocks[i] > 65535) throw new OperationError("Block out of range.");
|
||||
}
|
||||
return numBlocks;
|
||||
}
|
||||
|
@ -403,12 +394,13 @@ export function ipv6ToStr(ipv6, compact) {
|
|||
e = -1;
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
if (ipv6[i] === 0 && e === (i-1)) {
|
||||
if (ipv6[i] === 0 && e === i - 1) {
|
||||
e = i;
|
||||
} else if (ipv6[i] === 0) {
|
||||
s = i; e = i;
|
||||
s = i;
|
||||
e = i;
|
||||
}
|
||||
if (e >= 0 && (e-s) > (end - start)) {
|
||||
if (e >= 0 && e - s > end - start) {
|
||||
start = s;
|
||||
end = e;
|
||||
}
|
||||
|
@ -423,14 +415,13 @@ export function ipv6ToStr(ipv6, compact) {
|
|||
if (end === 7) output += ":";
|
||||
}
|
||||
}
|
||||
if (output[0] === ":")
|
||||
output = ":" + output;
|
||||
if (output[0] === ":") output = ":" + output;
|
||||
} else {
|
||||
for (i = 0; i < 8; i++) {
|
||||
output += Utils.hex(ipv6[i], 4) + ":";
|
||||
}
|
||||
}
|
||||
return output.slice(0, output.length-1);
|
||||
return output.slice(0, output.length - 1);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -467,12 +458,12 @@ export function genIpv6Mask(cidr) {
|
|||
let shift;
|
||||
|
||||
for (let i = 0; i < 8; i++) {
|
||||
if (cidr > ((i+1)*16)) {
|
||||
mask[i] = 0x0000FFFF;
|
||||
if (cidr > (i + 1) * 16) {
|
||||
mask[i] = 0x0000ffff;
|
||||
} else {
|
||||
shift = cidr-(i*16);
|
||||
shift = cidr - i * 16;
|
||||
if (shift < 0) shift = 0;
|
||||
mask[i] = ~((0x0000FFFF >>> shift) | 0xFFFF0000);
|
||||
mask[i] = ~((0x0000ffff >>> shift) | 0xffff0000);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -498,7 +489,6 @@ export function ipv4Compare(a, b) {
|
|||
* @returns {number}
|
||||
*/
|
||||
export function ipv6Compare(a, b) {
|
||||
|
||||
const a_ = strToIpv6(a),
|
||||
b_ = strToIpv6(b);
|
||||
|
||||
|
@ -510,7 +500,8 @@ export function ipv6Compare(a, b) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
const _LARGE_RANGE_ERROR = "The specified range contains more than 65,536 addresses. Running this query could crash your browser. If you want to run it, select the \"Allow large queries\" option. You are advised to turn off \"Auto Bake\" whilst editing large ranges.";
|
||||
const _LARGE_RANGE_ERROR
|
||||
= 'The specified range contains more than 65,536 addresses. Running this query could crash your browser. If you want to run it, select the "Allow large queries" option. You are advised to turn off "Auto Bake" whilst editing large ranges.';
|
||||
|
||||
/**
|
||||
* A regular expression that matches an IPv4 address
|
||||
|
@ -520,157 +511,158 @@ export const IPV4_REGEX = /^\s*((?:\d{1,3}\.){3}\d{1,3})\s*$/;
|
|||
/**
|
||||
* A regular expression that matches an IPv6 address
|
||||
*/
|
||||
export const IPV6_REGEX = /^\s*(((?=.*::)(?!.*::.+::)(::)?([\dA-F]{1,4}:(:|\b)|){5}|([\dA-F]{1,4}:){6})((([\dA-F]{1,4}((?!\4)::|:\b|(?![\dA-F])))|(?!\3\4)){2}|(((2[0-4]|1\d|[1-9])?\d|25[0-5])\.?\b){4}))\s*$/i;
|
||||
export const IPV6_REGEX
|
||||
= /^\s*(((?=.*::)(?!.*::.+::)(::)?([\dA-F]{1,4}:(:|\b)|){5}|([\dA-F]{1,4}:){6})((([\dA-F]{1,4}((?!\4)::|:\b|(?![\dA-F])))|(?!\3\4)){2}|(((2[0-4]|1\d|[1-9])?\d|25[0-5])\.?\b){4}))\s*$/i;
|
||||
|
||||
/**
|
||||
* Lookup table for Internet Protocols.
|
||||
* Taken from https://www.iana.org/assignments/protocol-numbers/protocol-numbers.xhtml
|
||||
*/
|
||||
export const protocolLookup = {
|
||||
0: {keyword: "HOPOPT", protocol: "IPv6 Hop-by-Hop Option"},
|
||||
1: {keyword: "ICMP", protocol: "Internet Control Message"},
|
||||
2: {keyword: "IGMP", protocol: "Internet Group Management"},
|
||||
3: {keyword: "GGP", protocol: "Gateway-to-Gateway"},
|
||||
4: {keyword: "IPv4", protocol: "IPv4 encapsulation"},
|
||||
5: {keyword: "ST", protocol: "Stream"},
|
||||
6: {keyword: "TCP", protocol: "Transmission Control"},
|
||||
7: {keyword: "CBT", protocol: "CBT"},
|
||||
8: {keyword: "EGP", protocol: "Exterior Gateway Protocol"},
|
||||
9: {keyword: "IGP", protocol: "any private interior gateway (used by Cisco for their IGRP)"},
|
||||
10: {keyword: "BBN-RCC-MON", protocol: "BBN RCC Monitoring"},
|
||||
11: {keyword: "NVP-II", protocol: "Network Voice Protocol"},
|
||||
12: {keyword: "PUP", protocol: "PUP"},
|
||||
13: {keyword: "ARGUS (deprecated)", protocol: "ARGUS"},
|
||||
14: {keyword: "EMCON", protocol: "EMCON"},
|
||||
15: {keyword: "XNET", protocol: "Cross Net Debugger"},
|
||||
16: {keyword: "CHAOS", protocol: "Chaos"},
|
||||
17: {keyword: "UDP", protocol: "User Datagram"},
|
||||
18: {keyword: "MUX", protocol: "Multiplexing"},
|
||||
19: {keyword: "DCN-MEAS", protocol: "DCN Measurement Subsystems"},
|
||||
20: {keyword: "HMP", protocol: "Host Monitoring"},
|
||||
21: {keyword: "PRM", protocol: "Packet Radio Measurement"},
|
||||
22: {keyword: "XNS-IDP", protocol: "XEROX NS IDP"},
|
||||
23: {keyword: "TRUNK-1", protocol: "Trunk-1"},
|
||||
24: {keyword: "TRUNK-2", protocol: "Trunk-2"},
|
||||
25: {keyword: "LEAF-1", protocol: "Leaf-1"},
|
||||
26: {keyword: "LEAF-2", protocol: "Leaf-2"},
|
||||
27: {keyword: "RDP", protocol: "Reliable Data Protocol"},
|
||||
28: {keyword: "IRTP", protocol: "Internet Reliable Transaction"},
|
||||
29: {keyword: "ISO-TP4", protocol: "ISO Transport Protocol Class 4"},
|
||||
30: {keyword: "NETBLT", protocol: "Bulk Data Transfer Protocol"},
|
||||
31: {keyword: "MFE-NSP", protocol: "MFE Network Services Protocol"},
|
||||
32: {keyword: "MERIT-INP", protocol: "MERIT Internodal Protocol"},
|
||||
33: {keyword: "DCCP", protocol: "Datagram Congestion Control Protocol"},
|
||||
34: {keyword: "3PC", protocol: "Third Party Connect Protocol"},
|
||||
35: {keyword: "IDPR", protocol: "Inter-Domain Policy Routing Protocol"},
|
||||
36: {keyword: "XTP", protocol: "XTP"},
|
||||
37: {keyword: "DDP", protocol: "Datagram Delivery Protocol"},
|
||||
38: {keyword: "IDPR-CMTP", protocol: "IDPR Control Message Transport Proto"},
|
||||
39: {keyword: "TP++", protocol: "TP++ Transport Protocol"},
|
||||
40: {keyword: "IL", protocol: "IL Transport Protocol"},
|
||||
41: {keyword: "IPv6", protocol: "IPv6 encapsulation"},
|
||||
42: {keyword: "SDRP", protocol: "Source Demand Routing Protocol"},
|
||||
43: {keyword: "IPv6-Route", protocol: "Routing Header for IPv6"},
|
||||
44: {keyword: "IPv6-Frag", protocol: "Fragment Header for IPv6"},
|
||||
45: {keyword: "IDRP", protocol: "Inter-Domain Routing Protocol"},
|
||||
46: {keyword: "RSVP", protocol: "Reservation Protocol"},
|
||||
47: {keyword: "GRE", protocol: "Generic Routing Encapsulation"},
|
||||
48: {keyword: "DSR", protocol: "Dynamic Source Routing Protocol"},
|
||||
49: {keyword: "BNA", protocol: "BNA"},
|
||||
50: {keyword: "ESP", protocol: "Encap Security Payload"},
|
||||
51: {keyword: "AH", protocol: "Authentication Header"},
|
||||
52: {keyword: "I-NLSP", protocol: "Integrated Net Layer Security TUBA"},
|
||||
53: {keyword: "SWIPE (deprecated)", protocol: "IP with Encryption"},
|
||||
54: {keyword: "NARP", protocol: "NBMA Address Resolution Protocol"},
|
||||
55: {keyword: "MOBILE", protocol: "IP Mobility"},
|
||||
56: {keyword: "TLSP", protocol: "Transport Layer Security Protocol using Kryptonet key management"},
|
||||
57: {keyword: "SKIP", protocol: "SKIP"},
|
||||
58: {keyword: "IPv6-ICMP", protocol: "ICMP for IPv6"},
|
||||
59: {keyword: "IPv6-NoNxt", protocol: "No Next Header for IPv6"},
|
||||
60: {keyword: "IPv6-Opts", protocol: "Destination Options for IPv6"},
|
||||
61: {keyword: "", protocol: "any host internal protocol"},
|
||||
62: {keyword: "CFTP", protocol: "CFTP"},
|
||||
63: {keyword: "", protocol: "any local network"},
|
||||
64: {keyword: "SAT-EXPAK", protocol: "SATNET and Backroom EXPAK"},
|
||||
65: {keyword: "KRYPTOLAN", protocol: "Kryptolan"},
|
||||
66: {keyword: "RVD", protocol: "MIT Remote Virtual Disk Protocol"},
|
||||
67: {keyword: "IPPC", protocol: "Internet Pluribus Packet Core"},
|
||||
68: {keyword: "", protocol: "any distributed file system"},
|
||||
69: {keyword: "SAT-MON", protocol: "SATNET Monitoring"},
|
||||
70: {keyword: "VISA", protocol: "VISA Protocol"},
|
||||
71: {keyword: "IPCV", protocol: "Internet Packet Core Utility"},
|
||||
72: {keyword: "CPNX", protocol: "Computer Protocol Network Executive"},
|
||||
73: {keyword: "CPHB", protocol: "Computer Protocol Heart Beat"},
|
||||
74: {keyword: "WSN", protocol: "Wang Span Network"},
|
||||
75: {keyword: "PVP", protocol: "Packet Video Protocol"},
|
||||
76: {keyword: "BR-SAT-MON", protocol: "Backroom SATNET Monitoring"},
|
||||
77: {keyword: "SUN-ND", protocol: "SUN ND PROTOCOL-Temporary"},
|
||||
78: {keyword: "WB-MON", protocol: "WIDEBAND Monitoring"},
|
||||
79: {keyword: "WB-EXPAK", protocol: "WIDEBAND EXPAK"},
|
||||
80: {keyword: "ISO-IP", protocol: "ISO Internet Protocol"},
|
||||
81: {keyword: "VMTP", protocol: "VMTP"},
|
||||
82: {keyword: "SECURE-VMTP", protocol: "SECURE-VMTP"},
|
||||
83: {keyword: "VINES", protocol: "VINES"},
|
||||
84: {keyword: "TTP", protocol: "Transaction Transport Protocol"},
|
||||
85: {keyword: "NSFNET-IGP", protocol: "NSFNET-IGP"},
|
||||
86: {keyword: "DGP", protocol: "Dissimilar Gateway Protocol"},
|
||||
87: {keyword: "TCF", protocol: "TCF"},
|
||||
88: {keyword: "EIGRP", protocol: "EIGRP"},
|
||||
89: {keyword: "OSPFIGP", protocol: "OSPFIGP"},
|
||||
90: {keyword: "Sprite-RPC", protocol: "Sprite RPC Protocol"},
|
||||
91: {keyword: "LARP", protocol: "Locus Address Resolution Protocol"},
|
||||
92: {keyword: "MTP", protocol: "Multicast Transport Protocol"},
|
||||
93: {keyword: "AX.25", protocol: "AX.25 Frames"},
|
||||
94: {keyword: "IPIP", protocol: "IP-within-IP Encapsulation Protocol"},
|
||||
95: {keyword: "MICP (deprecated)", protocol: "Mobile Internetworking Control Pro."},
|
||||
96: {keyword: "SCC-SP", protocol: "Semaphore Communications Sec. Pro."},
|
||||
97: {keyword: "ETHERIP", protocol: "Ethernet-within-IP Encapsulation"},
|
||||
98: {keyword: "ENCAP", protocol: "Encapsulation Header"},
|
||||
99: {keyword: "", protocol: "any private encryption scheme"},
|
||||
100: {keyword: "GMTP", protocol: "GMTP"},
|
||||
101: {keyword: "IFMP", protocol: "Ipsilon Flow Management Protocol"},
|
||||
102: {keyword: "PNNI", protocol: "PNNI over IP"},
|
||||
103: {keyword: "PIM", protocol: "Protocol Independent Multicast"},
|
||||
104: {keyword: "ARIS", protocol: "ARIS"},
|
||||
105: {keyword: "SCPS", protocol: "SCPS"},
|
||||
106: {keyword: "QNX", protocol: "QNX"},
|
||||
107: {keyword: "A/N", protocol: "Active Networks"},
|
||||
108: {keyword: "IPComp", protocol: "IP Payload Compression Protocol"},
|
||||
109: {keyword: "SNP", protocol: "Sitara Networks Protocol"},
|
||||
110: {keyword: "Compaq-Peer", protocol: "Compaq Peer Protocol"},
|
||||
111: {keyword: "IPX-in-IP", protocol: "IPX in IP"},
|
||||
112: {keyword: "VRRP", protocol: "Virtual Router Redundancy Protocol"},
|
||||
113: {keyword: "PGM", protocol: "PGM Reliable Transport Protocol"},
|
||||
114: {keyword: "", protocol: "any 0-hop protocol"},
|
||||
115: {keyword: "L2TP", protocol: "Layer Two Tunneling Protocol"},
|
||||
116: {keyword: "DDX", protocol: "D-II Data Exchange (DDX)"},
|
||||
117: {keyword: "IATP", protocol: "Interactive Agent Transfer Protocol"},
|
||||
118: {keyword: "STP", protocol: "Schedule Transfer Protocol"},
|
||||
119: {keyword: "SRP", protocol: "SpectraLink Radio Protocol"},
|
||||
120: {keyword: "UTI", protocol: "UTI"},
|
||||
121: {keyword: "SMP", protocol: "Simple Message Protocol"},
|
||||
122: {keyword: "SM (deprecated)", protocol: "Simple Multicast Protocol"},
|
||||
123: {keyword: "PTP", protocol: "Performance Transparency Protocol"},
|
||||
124: {keyword: "ISIS over IPv4", protocol: ""},
|
||||
125: {keyword: "FIRE", protocol: ""},
|
||||
126: {keyword: "CRTP", protocol: "Combat Radio Transport Protocol"},
|
||||
127: {keyword: "CRUDP", protocol: "Combat Radio User Datagram"},
|
||||
128: {keyword: "SSCOPMCE", protocol: ""},
|
||||
129: {keyword: "IPLT", protocol: ""},
|
||||
130: {keyword: "SPS", protocol: "Secure Packet Shield"},
|
||||
131: {keyword: "PIPE", protocol: "Private IP Encapsulation within IP"},
|
||||
132: {keyword: "SCTP", protocol: "Stream Control Transmission Protocol"},
|
||||
133: {keyword: "FC", protocol: "Fibre Channel"},
|
||||
134: {keyword: "RSVP-E2E-IGNORE", protocol: ""},
|
||||
135: {keyword: "Mobility Header", protocol: ""},
|
||||
136: {keyword: "UDPLite", protocol: ""},
|
||||
137: {keyword: "MPLS-in-IP", protocol: ""},
|
||||
138: {keyword: "manet", protocol: "MANET Protocols"},
|
||||
139: {keyword: "HIP", protocol: "Host Identity Protocol"},
|
||||
140: {keyword: "Shim6", protocol: "Shim6 Protocol"},
|
||||
141: {keyword: "WESP", protocol: "Wrapped Encapsulating Security Payload"},
|
||||
142: {keyword: "ROHC", protocol: "Robust Header Compression"},
|
||||
253: {keyword: "", protocol: "Use for experimentation and testing"},
|
||||
254: {keyword: "", protocol: "Use for experimentation and testing"},
|
||||
255: {keyword: "Reserved", protocol: ""}
|
||||
0: { keyword: "HOPOPT", protocol: "IPv6 Hop-by-Hop Option" },
|
||||
1: { keyword: "ICMP", protocol: "Internet Control Message" },
|
||||
2: { keyword: "IGMP", protocol: "Internet Group Management" },
|
||||
3: { keyword: "GGP", protocol: "Gateway-to-Gateway" },
|
||||
4: { keyword: "IPv4", protocol: "IPv4 encapsulation" },
|
||||
5: { keyword: "ST", protocol: "Stream" },
|
||||
6: { keyword: "TCP", protocol: "Transmission Control" },
|
||||
7: { keyword: "CBT", protocol: "CBT" },
|
||||
8: { keyword: "EGP", protocol: "Exterior Gateway Protocol" },
|
||||
9: { keyword: "IGP", protocol: "any private interior gateway (used by Cisco for their IGRP)" },
|
||||
10: { keyword: "BBN-RCC-MON", protocol: "BBN RCC Monitoring" },
|
||||
11: { keyword: "NVP-II", protocol: "Network Voice Protocol" },
|
||||
12: { keyword: "PUP", protocol: "PUP" },
|
||||
13: { keyword: "ARGUS (deprecated)", protocol: "ARGUS" },
|
||||
14: { keyword: "EMCON", protocol: "EMCON" },
|
||||
15: { keyword: "XNET", protocol: "Cross Net Debugger" },
|
||||
16: { keyword: "CHAOS", protocol: "Chaos" },
|
||||
17: { keyword: "UDP", protocol: "User Datagram" },
|
||||
18: { keyword: "MUX", protocol: "Multiplexing" },
|
||||
19: { keyword: "DCN-MEAS", protocol: "DCN Measurement Subsystems" },
|
||||
20: { keyword: "HMP", protocol: "Host Monitoring" },
|
||||
21: { keyword: "PRM", protocol: "Packet Radio Measurement" },
|
||||
22: { keyword: "XNS-IDP", protocol: "XEROX NS IDP" },
|
||||
23: { keyword: "TRUNK-1", protocol: "Trunk-1" },
|
||||
24: { keyword: "TRUNK-2", protocol: "Trunk-2" },
|
||||
25: { keyword: "LEAF-1", protocol: "Leaf-1" },
|
||||
26: { keyword: "LEAF-2", protocol: "Leaf-2" },
|
||||
27: { keyword: "RDP", protocol: "Reliable Data Protocol" },
|
||||
28: { keyword: "IRTP", protocol: "Internet Reliable Transaction" },
|
||||
29: { keyword: "ISO-TP4", protocol: "ISO Transport Protocol Class 4" },
|
||||
30: { keyword: "NETBLT", protocol: "Bulk Data Transfer Protocol" },
|
||||
31: { keyword: "MFE-NSP", protocol: "MFE Network Services Protocol" },
|
||||
32: { keyword: "MERIT-INP", protocol: "MERIT Internodal Protocol" },
|
||||
33: { keyword: "DCCP", protocol: "Datagram Congestion Control Protocol" },
|
||||
34: { keyword: "3PC", protocol: "Third Party Connect Protocol" },
|
||||
35: { keyword: "IDPR", protocol: "Inter-Domain Policy Routing Protocol" },
|
||||
36: { keyword: "XTP", protocol: "XTP" },
|
||||
37: { keyword: "DDP", protocol: "Datagram Delivery Protocol" },
|
||||
38: { keyword: "IDPR-CMTP", protocol: "IDPR Control Message Transport Proto" },
|
||||
39: { keyword: "TP++", protocol: "TP++ Transport Protocol" },
|
||||
40: { keyword: "IL", protocol: "IL Transport Protocol" },
|
||||
41: { keyword: "IPv6", protocol: "IPv6 encapsulation" },
|
||||
42: { keyword: "SDRP", protocol: "Source Demand Routing Protocol" },
|
||||
43: { keyword: "IPv6-Route", protocol: "Routing Header for IPv6" },
|
||||
44: { keyword: "IPv6-Frag", protocol: "Fragment Header for IPv6" },
|
||||
45: { keyword: "IDRP", protocol: "Inter-Domain Routing Protocol" },
|
||||
46: { keyword: "RSVP", protocol: "Reservation Protocol" },
|
||||
47: { keyword: "GRE", protocol: "Generic Routing Encapsulation" },
|
||||
48: { keyword: "DSR", protocol: "Dynamic Source Routing Protocol" },
|
||||
49: { keyword: "BNA", protocol: "BNA" },
|
||||
50: { keyword: "ESP", protocol: "Encap Security Payload" },
|
||||
51: { keyword: "AH", protocol: "Authentication Header" },
|
||||
52: { keyword: "I-NLSP", protocol: "Integrated Net Layer Security TUBA" },
|
||||
53: { keyword: "SWIPE (deprecated)", protocol: "IP with Encryption" },
|
||||
54: { keyword: "NARP", protocol: "NBMA Address Resolution Protocol" },
|
||||
55: { keyword: "MOBILE", protocol: "IP Mobility" },
|
||||
56: { keyword: "TLSP", protocol: "Transport Layer Security Protocol using Kryptonet key management" },
|
||||
57: { keyword: "SKIP", protocol: "SKIP" },
|
||||
58: { keyword: "IPv6-ICMP", protocol: "ICMP for IPv6" },
|
||||
59: { keyword: "IPv6-NoNxt", protocol: "No Next Header for IPv6" },
|
||||
60: { keyword: "IPv6-Opts", protocol: "Destination Options for IPv6" },
|
||||
61: { keyword: "", protocol: "any host internal protocol" },
|
||||
62: { keyword: "CFTP", protocol: "CFTP" },
|
||||
63: { keyword: "", protocol: "any local network" },
|
||||
64: { keyword: "SAT-EXPAK", protocol: "SATNET and Backroom EXPAK" },
|
||||
65: { keyword: "KRYPTOLAN", protocol: "Kryptolan" },
|
||||
66: { keyword: "RVD", protocol: "MIT Remote Virtual Disk Protocol" },
|
||||
67: { keyword: "IPPC", protocol: "Internet Pluribus Packet Core" },
|
||||
68: { keyword: "", protocol: "any distributed file system" },
|
||||
69: { keyword: "SAT-MON", protocol: "SATNET Monitoring" },
|
||||
70: { keyword: "VISA", protocol: "VISA Protocol" },
|
||||
71: { keyword: "IPCV", protocol: "Internet Packet Core Utility" },
|
||||
72: { keyword: "CPNX", protocol: "Computer Protocol Network Executive" },
|
||||
73: { keyword: "CPHB", protocol: "Computer Protocol Heart Beat" },
|
||||
74: { keyword: "WSN", protocol: "Wang Span Network" },
|
||||
75: { keyword: "PVP", protocol: "Packet Video Protocol" },
|
||||
76: { keyword: "BR-SAT-MON", protocol: "Backroom SATNET Monitoring" },
|
||||
77: { keyword: "SUN-ND", protocol: "SUN ND PROTOCOL-Temporary" },
|
||||
78: { keyword: "WB-MON", protocol: "WIDEBAND Monitoring" },
|
||||
79: { keyword: "WB-EXPAK", protocol: "WIDEBAND EXPAK" },
|
||||
80: { keyword: "ISO-IP", protocol: "ISO Internet Protocol" },
|
||||
81: { keyword: "VMTP", protocol: "VMTP" },
|
||||
82: { keyword: "SECURE-VMTP", protocol: "SECURE-VMTP" },
|
||||
83: { keyword: "VINES", protocol: "VINES" },
|
||||
84: { keyword: "TTP", protocol: "Transaction Transport Protocol" },
|
||||
85: { keyword: "NSFNET-IGP", protocol: "NSFNET-IGP" },
|
||||
86: { keyword: "DGP", protocol: "Dissimilar Gateway Protocol" },
|
||||
87: { keyword: "TCF", protocol: "TCF" },
|
||||
88: { keyword: "EIGRP", protocol: "EIGRP" },
|
||||
89: { keyword: "OSPFIGP", protocol: "OSPFIGP" },
|
||||
90: { keyword: "Sprite-RPC", protocol: "Sprite RPC Protocol" },
|
||||
91: { keyword: "LARP", protocol: "Locus Address Resolution Protocol" },
|
||||
92: { keyword: "MTP", protocol: "Multicast Transport Protocol" },
|
||||
93: { keyword: "AX.25", protocol: "AX.25 Frames" },
|
||||
94: { keyword: "IPIP", protocol: "IP-within-IP Encapsulation Protocol" },
|
||||
95: { keyword: "MICP (deprecated)", protocol: "Mobile Internetworking Control Pro." },
|
||||
96: { keyword: "SCC-SP", protocol: "Semaphore Communications Sec. Pro." },
|
||||
97: { keyword: "ETHERIP", protocol: "Ethernet-within-IP Encapsulation" },
|
||||
98: { keyword: "ENCAP", protocol: "Encapsulation Header" },
|
||||
99: { keyword: "", protocol: "any private encryption scheme" },
|
||||
100: { keyword: "GMTP", protocol: "GMTP" },
|
||||
101: { keyword: "IFMP", protocol: "Ipsilon Flow Management Protocol" },
|
||||
102: { keyword: "PNNI", protocol: "PNNI over IP" },
|
||||
103: { keyword: "PIM", protocol: "Protocol Independent Multicast" },
|
||||
104: { keyword: "ARIS", protocol: "ARIS" },
|
||||
105: { keyword: "SCPS", protocol: "SCPS" },
|
||||
106: { keyword: "QNX", protocol: "QNX" },
|
||||
107: { keyword: "A/N", protocol: "Active Networks" },
|
||||
108: { keyword: "IPComp", protocol: "IP Payload Compression Protocol" },
|
||||
109: { keyword: "SNP", protocol: "Sitara Networks Protocol" },
|
||||
110: { keyword: "Compaq-Peer", protocol: "Compaq Peer Protocol" },
|
||||
111: { keyword: "IPX-in-IP", protocol: "IPX in IP" },
|
||||
112: { keyword: "VRRP", protocol: "Virtual Router Redundancy Protocol" },
|
||||
113: { keyword: "PGM", protocol: "PGM Reliable Transport Protocol" },
|
||||
114: { keyword: "", protocol: "any 0-hop protocol" },
|
||||
115: { keyword: "L2TP", protocol: "Layer Two Tunneling Protocol" },
|
||||
116: { keyword: "DDX", protocol: "D-II Data Exchange (DDX)" },
|
||||
117: { keyword: "IATP", protocol: "Interactive Agent Transfer Protocol" },
|
||||
118: { keyword: "STP", protocol: "Schedule Transfer Protocol" },
|
||||
119: { keyword: "SRP", protocol: "SpectraLink Radio Protocol" },
|
||||
120: { keyword: "UTI", protocol: "UTI" },
|
||||
121: { keyword: "SMP", protocol: "Simple Message Protocol" },
|
||||
122: { keyword: "SM (deprecated)", protocol: "Simple Multicast Protocol" },
|
||||
123: { keyword: "PTP", protocol: "Performance Transparency Protocol" },
|
||||
124: { keyword: "ISIS over IPv4", protocol: "" },
|
||||
125: { keyword: "FIRE", protocol: "" },
|
||||
126: { keyword: "CRTP", protocol: "Combat Radio Transport Protocol" },
|
||||
127: { keyword: "CRUDP", protocol: "Combat Radio User Datagram" },
|
||||
128: { keyword: "SSCOPMCE", protocol: "" },
|
||||
129: { keyword: "IPLT", protocol: "" },
|
||||
130: { keyword: "SPS", protocol: "Secure Packet Shield" },
|
||||
131: { keyword: "PIPE", protocol: "Private IP Encapsulation within IP" },
|
||||
132: { keyword: "SCTP", protocol: "Stream Control Transmission Protocol" },
|
||||
133: { keyword: "FC", protocol: "Fibre Channel" },
|
||||
134: { keyword: "RSVP-E2E-IGNORE", protocol: "" },
|
||||
135: { keyword: "Mobility Header", protocol: "" },
|
||||
136: { keyword: "UDPLite", protocol: "" },
|
||||
137: { keyword: "MPLS-in-IP", protocol: "" },
|
||||
138: { keyword: "manet", protocol: "MANET Protocols" },
|
||||
139: { keyword: "HIP", protocol: "Host Identity Protocol" },
|
||||
140: { keyword: "Shim6", protocol: "Shim6 Protocol" },
|
||||
141: { keyword: "WESP", protocol: "Wrapped Encapsulating Security Payload" },
|
||||
142: { keyword: "ROHC", protocol: "Robust Header Compression" },
|
||||
253: { keyword: "", protocol: "Use for experimentation and testing" },
|
||||
254: { keyword: "", protocol: "Use for experimentation and testing" },
|
||||
255: { keyword: "Reserved", protocol: "" }
|
||||
};
|
||||
|
|
|
@ -16,7 +16,7 @@ import OperationError from "../errors/OperationError.mjs";
|
|||
* @param {boolean} fast
|
||||
* @returns {jimp}
|
||||
*/
|
||||
export function gaussianBlur (input, radius) {
|
||||
export function gaussianBlur(input, radius) {
|
||||
try {
|
||||
// From http://blog.ivank.net/fastest-gaussian-blur.html
|
||||
const boxes = boxesForGauss(radius, 3);
|
||||
|
@ -37,7 +37,7 @@ export function gaussianBlur (input, radius) {
|
|||
* @returns {Array}
|
||||
*/
|
||||
function boxesForGauss(radius, numBoxes) {
|
||||
const idealWidth = Math.sqrt((12 * radius * radius / numBoxes) + 1);
|
||||
const idealWidth = Math.sqrt((12 * radius * radius) / numBoxes + 1);
|
||||
|
||||
let wl = Math.floor(idealWidth);
|
||||
|
||||
|
@ -64,7 +64,7 @@ function boxesForGauss(radius, numBoxes) {
|
|||
* @param {number} radius
|
||||
* @returns {jimp}
|
||||
*/
|
||||
function boxBlur (source, radius) {
|
||||
function boxBlur(source, radius) {
|
||||
const width = source.bitmap.width;
|
||||
const height = source.bitmap.height;
|
||||
let output = source.clone();
|
||||
|
@ -84,7 +84,7 @@ function boxBlur (source, radius) {
|
|||
* @param {number} radius
|
||||
* @returns {jimp}
|
||||
*/
|
||||
function boxBlurH (source, output, width, height, radius) {
|
||||
function boxBlurH(source, output, width, height, radius) {
|
||||
const iarr = 1 / (radius + radius + 1);
|
||||
for (let i = 0; i < height; i++) {
|
||||
let ti = 0,
|
||||
|
@ -171,7 +171,7 @@ function boxBlurH (source, output, width, height, radius) {
|
|||
* @param {number} radius
|
||||
* @returns {jimp}
|
||||
*/
|
||||
function boxBlurV (source, output, width, height, radius) {
|
||||
function boxBlurV(source, output, width, height, radius) {
|
||||
const iarr = 1 / (radius + radius + 1);
|
||||
for (let i = 0; i < width; i++) {
|
||||
let ti = 0,
|
||||
|
|
|
@ -6,19 +6,7 @@
|
|||
* @license Apache-2.0
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* List of the JWT algorithms that can be used
|
||||
*/
|
||||
export const JWT_ALGORITHMS = [
|
||||
"HS256",
|
||||
"HS384",
|
||||
"HS512",
|
||||
"RS256",
|
||||
"RS384",
|
||||
"RS512",
|
||||
"ES256",
|
||||
"ES384",
|
||||
"ES512",
|
||||
"None"
|
||||
];
|
||||
export const JWT_ALGORITHMS = ["HS256", "HS384", "HS512", "RS256", "RS384", "RS512", "ES256", "ES384", "ES512", "None"];
|
||||
|
|
|
@ -13,8 +13,7 @@ const tiles = [];
|
|||
* Initialises the tiles with values and positions.
|
||||
*/
|
||||
export function initTiles() {
|
||||
for (let i = 0; i < 49; i++)
|
||||
tiles.push([letters.charAt(i), [Math.floor(i/7), i % 7]]);
|
||||
for (let i = 0; i < 49; i++) tiles.push([letters.charAt(i), [Math.floor(i / 7), i % 7]]);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -27,21 +26,19 @@ export function initTiles() {
|
|||
*/
|
||||
function rotateDown(key, col, n) {
|
||||
const lines = [];
|
||||
for (let i = 0; i < 7; i++)
|
||||
lines.push(key.slice(i*7, (i + 1) * 7));
|
||||
for (let i = 0; i < 7; i++) lines.push(key.slice(i * 7, (i + 1) * 7));
|
||||
const lefts = [];
|
||||
let mids = [];
|
||||
const rights = [];
|
||||
lines.forEach((element) => {
|
||||
lefts.push(element.slice(0, col));
|
||||
mids.push(element.charAt(col));
|
||||
rights.push(element.slice(col+1));
|
||||
rights.push(element.slice(col + 1));
|
||||
});
|
||||
n = (7 - n % 7) % 7;
|
||||
n = (7 - (n % 7)) % 7;
|
||||
mids = mids.slice(n).concat(mids.slice(0, n));
|
||||
let result = "";
|
||||
for (let i = 0; i < 7; i++)
|
||||
result += lefts[i] + mids[i] + rights[i];
|
||||
for (let i = 0; i < 7; i++) result += lefts[i] + mids[i] + rights[i];
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -55,7 +52,7 @@ function rotateDown(key, col, n) {
|
|||
*/
|
||||
function rotateRight(key, row, n) {
|
||||
const mid = key.slice(row * 7, (row + 1) * 7);
|
||||
n = (7 - n % 7) % 7;
|
||||
n = (7 - (n % 7)) % 7;
|
||||
return key.slice(0, 7 * row) + mid.slice(n) + mid.slice(0, n) + key.slice(7 * (row + 1));
|
||||
}
|
||||
|
||||
|
@ -66,9 +63,7 @@ function rotateRight(key, row, n) {
|
|||
* @returns {string}
|
||||
*/
|
||||
function findIx(letter) {
|
||||
for (let i = 0; i < tiles.length; i++)
|
||||
if (tiles[i][0] === letter)
|
||||
return tiles[i][1];
|
||||
for (let i = 0; i < tiles.length; i++) if (tiles[i][0] === letter) return tiles[i][1];
|
||||
throw new OperationError("Letter " + letter + " is not included in LS47");
|
||||
}
|
||||
|
||||
|
@ -95,17 +90,13 @@ export function deriveKey(password) {
|
|||
* @param {string} key
|
||||
*/
|
||||
function checkKey(key) {
|
||||
if (key.length !== letters.length)
|
||||
throw new OperationError("Wrong key size");
|
||||
if (key.length !== letters.length) throw new OperationError("Wrong key size");
|
||||
const counts = new Array();
|
||||
for (let i = 0; i < letters.length; i++)
|
||||
counts[letters.charAt(i)] = 0;
|
||||
for (let i = 0; i < letters.length; i++) counts[letters.charAt(i)] = 0;
|
||||
for (const elem of letters) {
|
||||
if (letters.indexOf(elem) === -1)
|
||||
throw new OperationError("Letter " + elem + " not in LS47");
|
||||
if (letters.indexOf(elem) === -1) throw new OperationError("Letter " + elem + " not in LS47");
|
||||
counts[elem]++;
|
||||
if (counts[elem] > 1)
|
||||
throw new OperationError("Letter duplicated in the key");
|
||||
if (counts[elem] > 1) throw new OperationError("Letter duplicated in the key");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -116,10 +107,9 @@ function checkKey(key) {
|
|||
* @param {string} letter
|
||||
* @returns {object}
|
||||
*/
|
||||
function findPos (key, letter) {
|
||||
function findPos(key, letter) {
|
||||
const index = key.indexOf(letter);
|
||||
if (index >= 0 && index < 49)
|
||||
return [Math.floor(index/7), index%7];
|
||||
if (index >= 0 && index < 49) return [Math.floor(index / 7), index % 7];
|
||||
throw new OperationError("Letter " + letter + " is not in the key");
|
||||
}
|
||||
|
||||
|
@ -131,7 +121,7 @@ function findPos (key, letter) {
|
|||
* @returns {string}
|
||||
*/
|
||||
function findAtPos(key, coord) {
|
||||
return key.charAt(coord[1] + (coord[0] * 7));
|
||||
return key.charAt(coord[1] + coord[0] * 7);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -157,7 +147,7 @@ function addPos(a, b) {
|
|||
function subPos(a, b) {
|
||||
const asub = a[0] - b[0];
|
||||
const bsub = a[1] - b[1];
|
||||
return [asub - (Math.floor(asub/7) * 7), bsub - (Math.floor(bsub/7) * 7)];
|
||||
return [asub - Math.floor(asub / 7) * 7, bsub - Math.floor(bsub / 7) * 7];
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -226,7 +216,7 @@ export function encryptPad(key, plaintext, signature, paddingSize) {
|
|||
for (let i = 0; i < paddingSize; i++) {
|
||||
padding += letters.charAt(Math.floor(Math.random() * letters.length));
|
||||
}
|
||||
return encrypt(key, padding+plaintext+"---"+signature);
|
||||
return encrypt(key, padding + plaintext + "---" + signature);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -64,7 +64,7 @@ export function decompress(compressed) {
|
|||
|
||||
const displacement = getDisplacement(decompressed.length - doffset - 1);
|
||||
const symbolOffset = (pointer >> (12 - displacement)) + 1;
|
||||
const symbolLength = (pointer & (0xFFF >> displacement)) + 2;
|
||||
const symbolLength = (pointer & (0xfff >> displacement)) + 2;
|
||||
const shiftOffset = decompressed.length - symbolOffset;
|
||||
|
||||
for (let shiftDelta = 0; shiftDelta < symbolLength + 1; shiftDelta++) {
|
||||
|
|
|
@ -11,11 +11,11 @@ import LZString from "lz-string";
|
|||
export const COMPRESSION_OUTPUT_FORMATS = ["default", "UTF16", "Base64"];
|
||||
export const COMPRESSION_FUNCTIONS = {
|
||||
"default": LZString.compress,
|
||||
"UTF16": LZString.compressToUTF16,
|
||||
"Base64": LZString.compressToBase64,
|
||||
"UTF16": LZString.compressToUTF16,
|
||||
"Base64": LZString.compressToBase64
|
||||
};
|
||||
export const DECOMPRESSION_FUNCTIONS = {
|
||||
"default": LZString.decompress,
|
||||
"UTF16": LZString.decompressFromUTF16,
|
||||
"Base64": LZString.decompressFromBase64,
|
||||
"UTF16": LZString.decompressFromUTF16,
|
||||
"Base64": LZString.decompressFromBase64
|
||||
};
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
* @param {number} length
|
||||
* @returns {string}
|
||||
*/
|
||||
export function GenerateParagraphs(length=3) {
|
||||
export function GenerateParagraphs(length = 3) {
|
||||
const paragraphs = [];
|
||||
while (paragraphs.length < length) {
|
||||
const paragraphLength = getRandomLength(PARAGRAPH_LENGTH_MEAN, PARAGRAPH_LENGTH_STD_DEV);
|
||||
|
@ -24,19 +24,18 @@ export function GenerateParagraphs(length=3) {
|
|||
}
|
||||
paragraphs.push(formatParagraph(sentences));
|
||||
}
|
||||
paragraphs[paragraphs.length-1] = paragraphs[paragraphs.length-1].slice(0, -2);
|
||||
paragraphs[paragraphs.length - 1] = paragraphs[paragraphs.length - 1].slice(0, -2);
|
||||
paragraphs[0] = replaceStart(paragraphs[0]);
|
||||
return paragraphs.join("");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Generate lorem ipsum sentences.
|
||||
*
|
||||
* @param {number} length
|
||||
* @returns {string}
|
||||
*/
|
||||
export function GenerateSentences(length=3) {
|
||||
export function GenerateSentences(length = 3) {
|
||||
const sentences = [];
|
||||
while (sentences.length < length) {
|
||||
const sentenceLength = getRandomLength(SENTENCE_LENGTH_MEAN, SENTENCE_LENGTH_STD_DEV);
|
||||
|
@ -47,33 +46,30 @@ export function GenerateSentences(length=3) {
|
|||
return paragraphs.join("");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Generate lorem ipsum words.
|
||||
*
|
||||
* @param {number} length
|
||||
* @returns {string}
|
||||
*/
|
||||
export function GenerateWords(length=3) {
|
||||
export function GenerateWords(length = 3) {
|
||||
const words = getWords(length);
|
||||
const sentences = wordsToSentences(words);
|
||||
const paragraphs = sentencesToParagraphs(sentences);
|
||||
return paragraphs.join("");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Generate lorem ipsum bytes.
|
||||
*
|
||||
* @param {number} length
|
||||
* @returns {string}
|
||||
*/
|
||||
export function GenerateBytes(length=3) {
|
||||
const str = GenerateWords(length/3);
|
||||
export function GenerateBytes(length = 3) {
|
||||
const str = GenerateWords(length / 3);
|
||||
return str.slice(0, length);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get array of randomly selected words from the lorem ipsum wordList.
|
||||
*
|
||||
|
@ -81,7 +77,7 @@ export function GenerateBytes(length=3) {
|
|||
* @returns {string[]}
|
||||
* @private
|
||||
*/
|
||||
function getWords(length=3) {
|
||||
function getWords(length = 3) {
|
||||
const words = [];
|
||||
let word;
|
||||
let previousWord;
|
||||
|
@ -95,7 +91,6 @@ function getWords(length=3) {
|
|||
return words;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Convert an array of words into an array of sentences
|
||||
*
|
||||
|
@ -116,7 +111,6 @@ function wordsToSentences(words) {
|
|||
return sentences;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Convert an array of sentences into an array of paragraphs
|
||||
*
|
||||
|
@ -130,12 +124,11 @@ function sentencesToParagraphs(sentences) {
|
|||
const paragraphLength = getRandomLength(PARAGRAPH_LENGTH_MEAN, PARAGRAPH_LENGTH_STD_DEV);
|
||||
paragraphs.push(formatParagraph(sentences.splice(0, paragraphLength)));
|
||||
}
|
||||
paragraphs[paragraphs.length-1] = paragraphs[paragraphs.length-1].slice(0, -1);
|
||||
paragraphs[paragraphs.length - 1] = paragraphs[paragraphs.length - 1].slice(0, -1);
|
||||
paragraphs[0] = replaceStart(paragraphs[0]);
|
||||
return paragraphs;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Format an array of words into a sentence.
|
||||
*
|
||||
|
@ -146,8 +139,8 @@ function sentencesToParagraphs(sentences) {
|
|||
function formatSentence(words) {
|
||||
// 0.35 chance of a comma being added randomly to the sentence.
|
||||
if (Math.random() < PROBABILITY_OF_A_COMMA) {
|
||||
const pos = Math.round(Math.random()*(words.length-1));
|
||||
words[pos] +=",";
|
||||
const pos = Math.round(Math.random() * (words.length - 1));
|
||||
words[pos] += ",";
|
||||
}
|
||||
let sentence = words.join(" ");
|
||||
sentence = sentence.charAt(0).toUpperCase() + sentence.slice(1);
|
||||
|
@ -155,7 +148,6 @@ function formatSentence(words) {
|
|||
return sentence;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Format an array of sentences into a paragraph.
|
||||
*
|
||||
|
@ -169,7 +161,6 @@ function formatParagraph(sentences) {
|
|||
return paragraph;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get a random number based on a mean and standard deviation.
|
||||
*
|
||||
|
@ -181,12 +172,11 @@ function formatParagraph(sentences) {
|
|||
function getRandomLength(mean, stdDev) {
|
||||
let length;
|
||||
do {
|
||||
length = Math.round((Math.random()*2-1)+(Math.random()*2-1)+(Math.random()*2-1)*stdDev+mean);
|
||||
length = Math.round(Math.random() * 2 - 1 + (Math.random() * 2 - 1) + (Math.random() * 2 - 1) * stdDev + mean);
|
||||
} while (length <= 0);
|
||||
return length;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Replace first 5 words with "Lorem ipsum dolor sit amet"
|
||||
*
|
||||
|
@ -208,7 +198,6 @@ function replaceStart(str) {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
const SENTENCE_LENGTH_MEAN = 15;
|
||||
const SENTENCE_LENGTH_STD_DEV = 9;
|
||||
const PARAGRAPH_LENGTH_MEAN = 5;
|
||||
|
@ -216,15 +205,66 @@ const PARAGRAPH_LENGTH_STD_DEV = 2;
|
|||
const PROBABILITY_OF_A_COMMA = 0.35;
|
||||
|
||||
const wordList = [
|
||||
"ad", "adipisicing", "aliqua", "aliquip", "amet", "anim",
|
||||
"aute", "cillum", "commodo", "consectetur", "consequat", "culpa",
|
||||
"cupidatat", "deserunt", "do", "dolor", "dolore", "duis",
|
||||
"ea", "eiusmod", "elit", "enim", "esse", "est",
|
||||
"et", "eu", "ex", "excepteur", "exercitation", "fugiat",
|
||||
"id", "in", "incididunt", "ipsum", "irure", "labore",
|
||||
"laboris", "laborum", "Lorem", "magna", "minim", "mollit",
|
||||
"nisi", "non", "nostrud", "nulla", "occaecat", "officia",
|
||||
"pariatur", "proident", "qui", "quis", "reprehenderit", "sint",
|
||||
"sit", "sunt", "tempor", "ullamco", "ut", "velit",
|
||||
"veniam", "voluptate",
|
||||
"ad",
|
||||
"adipisicing",
|
||||
"aliqua",
|
||||
"aliquip",
|
||||
"amet",
|
||||
"anim",
|
||||
"aute",
|
||||
"cillum",
|
||||
"commodo",
|
||||
"consectetur",
|
||||
"consequat",
|
||||
"culpa",
|
||||
"cupidatat",
|
||||
"deserunt",
|
||||
"do",
|
||||
"dolor",
|
||||
"dolore",
|
||||
"duis",
|
||||
"ea",
|
||||
"eiusmod",
|
||||
"elit",
|
||||
"enim",
|
||||
"esse",
|
||||
"est",
|
||||
"et",
|
||||
"eu",
|
||||
"ex",
|
||||
"excepteur",
|
||||
"exercitation",
|
||||
"fugiat",
|
||||
"id",
|
||||
"in",
|
||||
"incididunt",
|
||||
"ipsum",
|
||||
"irure",
|
||||
"labore",
|
||||
"laboris",
|
||||
"laborum",
|
||||
"Lorem",
|
||||
"magna",
|
||||
"minim",
|
||||
"mollit",
|
||||
"nisi",
|
||||
"non",
|
||||
"nostrud",
|
||||
"nulla",
|
||||
"occaecat",
|
||||
"officia",
|
||||
"pariatur",
|
||||
"proident",
|
||||
"qui",
|
||||
"quis",
|
||||
"reprehenderit",
|
||||
"sint",
|
||||
"sit",
|
||||
"sunt",
|
||||
"tempor",
|
||||
"ullamco",
|
||||
"ut",
|
||||
"velit",
|
||||
"veniam",
|
||||
"voluptate"
|
||||
];
|
||||
|
|
|
@ -7,9 +7,9 @@
|
|||
*/
|
||||
|
||||
export const SWITCHES = [
|
||||
{name: "Up (.)", value: "."},
|
||||
{name: "Centre", value: ""},
|
||||
{name: "Down (x)", value: "x"}
|
||||
{ name: "Up (.)", value: "." },
|
||||
{ name: "Centre", value: "" },
|
||||
{ name: "Down (x)", value: "x" }
|
||||
];
|
||||
|
||||
export const VALID_ITA2 = "ABCDEFGHIJKLMNOPQRSTUVWXYZ34589+-./";
|
||||
|
@ -74,83 +74,178 @@ export const ROTOR_SIZES = {
|
|||
export const INIT_PATTERNS = {
|
||||
"No Pattern": {
|
||||
"X": {
|
||||
1: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
||||
1: [
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0
|
||||
],
|
||||
2: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
||||
3: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
||||
4: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
||||
5: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
|
||||
},
|
||||
"S": {
|
||||
1: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
||||
2: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
||||
3: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
||||
4: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
||||
5: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
|
||||
1: [
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0
|
||||
],
|
||||
2: [
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||
],
|
||||
3: [
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||
],
|
||||
4: [
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||
],
|
||||
5: [
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||
]
|
||||
},
|
||||
"M": {
|
||||
1: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
||||
2: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
|
||||
1: [
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||
],
|
||||
2: [
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0
|
||||
]
|
||||
}
|
||||
|
||||
},
|
||||
"KH Pattern": {
|
||||
"X": {
|
||||
1: [0, 1, 0, 0, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0],
|
||||
1: [
|
||||
0, 1, 0, 0, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0,
|
||||
1, 1, 1, 1, 0, 0
|
||||
],
|
||||
2: [1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0],
|
||||
3: [0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0],
|
||||
4: [1, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0],
|
||||
5: [1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0]
|
||||
},
|
||||
"S": {
|
||||
1: [0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1],
|
||||
2: [0, 1, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1],
|
||||
3: [0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1],
|
||||
4: [0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 0, 0, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0],
|
||||
5: [1, 1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0]
|
||||
1: [
|
||||
0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
|
||||
0, 0, 1, 0, 1, 1, 0, 1
|
||||
],
|
||||
2: [
|
||||
0, 1, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 1,
|
||||
0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1
|
||||
],
|
||||
3: [
|
||||
0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 1, 0, 1, 0,
|
||||
1, 0, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1
|
||||
],
|
||||
4: [
|
||||
0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 0, 0, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0,
|
||||
1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0
|
||||
],
|
||||
5: [
|
||||
1, 1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
|
||||
0, 1, 1, 0, 0, 1, 1, 1, 1, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0
|
||||
]
|
||||
},
|
||||
"M": {
|
||||
1: [0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0],
|
||||
2: [1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0]
|
||||
"M": {
|
||||
1: [
|
||||
0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0,
|
||||
1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0
|
||||
],
|
||||
2: [
|
||||
1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0,
|
||||
0, 0
|
||||
]
|
||||
}
|
||||
},
|
||||
"ZMUG Pattern": {
|
||||
"ZMUG Pattern": {
|
||||
"X": {
|
||||
1: [0, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0],
|
||||
1: [
|
||||
0, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1,
|
||||
1, 0, 0, 1, 1, 0
|
||||
],
|
||||
2: [1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0],
|
||||
3: [0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 0],
|
||||
4: [1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 1, 0, 0, 1, 0, 1],
|
||||
5: [0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 1]
|
||||
},
|
||||
"S": {
|
||||
1: [1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0],
|
||||
2: [0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 1, 1],
|
||||
3: [0, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1],
|
||||
4: [0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 1],
|
||||
5: [1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0]
|
||||
1: [
|
||||
1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1,
|
||||
0, 0, 1, 1, 1, 0, 0, 0
|
||||
],
|
||||
2: [
|
||||
0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1,
|
||||
1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 1, 1
|
||||
],
|
||||
3: [
|
||||
0, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1,
|
||||
1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1
|
||||
],
|
||||
4: [
|
||||
0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0,
|
||||
0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 1
|
||||
],
|
||||
5: [
|
||||
1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1,
|
||||
1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0
|
||||
]
|
||||
},
|
||||
"M": {
|
||||
1: [1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1],
|
||||
2: [0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1]
|
||||
1: [
|
||||
1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0,
|
||||
1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1
|
||||
],
|
||||
2: [
|
||||
0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1,
|
||||
1, 1
|
||||
]
|
||||
}
|
||||
},
|
||||
"BREAM Pattern": {
|
||||
"X": {
|
||||
1: [0, 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0],
|
||||
1: [
|
||||
0, 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1,
|
||||
1, 1, 1, 0, 0, 0
|
||||
],
|
||||
2: [0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1],
|
||||
3: [1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0],
|
||||
4: [1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0],
|
||||
5: [0, 1, 1, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 0, 0, 1, 0]
|
||||
},
|
||||
"S": {
|
||||
1: [0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0],
|
||||
2: [1, 1, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 0],
|
||||
3: [1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1],
|
||||
4: [0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1],
|
||||
5: [1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0]
|
||||
1: [
|
||||
0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1,
|
||||
0, 1, 0, 1, 0, 1, 0, 0
|
||||
],
|
||||
2: [
|
||||
1, 1, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 1, 0,
|
||||
1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 0
|
||||
],
|
||||
3: [
|
||||
1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 0, 0,
|
||||
1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1
|
||||
],
|
||||
4: [
|
||||
0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 1, 1,
|
||||
0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1
|
||||
],
|
||||
5: [
|
||||
1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1,
|
||||
1, 0, 1, 1, 1, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0
|
||||
]
|
||||
},
|
||||
"M": {
|
||||
1: [1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 1, 1, 1],
|
||||
2: [0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1]
|
||||
1: [
|
||||
1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1,
|
||||
0, 1, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 1, 1, 1
|
||||
],
|
||||
2: [
|
||||
0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1,
|
||||
0, 1
|
||||
]
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -20,7 +20,7 @@ const promisify = es6promisify.default ? es6promisify.default.promisify : es6pro
|
|||
* Progress callback
|
||||
*/
|
||||
export const ASP = kbpgp.ASP({
|
||||
"progress_hook": info => {
|
||||
"progress_hook": (info) => {
|
||||
let msg = "";
|
||||
|
||||
switch (info.what) {
|
||||
|
@ -46,8 +46,7 @@ export const ASP = kbpgp.ASP({
|
|||
msg = `Stage: ${info.what}`;
|
||||
}
|
||||
|
||||
if (isWorkerEnvironment())
|
||||
self.sendStatusMessage(msg);
|
||||
if (isWorkerEnvironment()) self.sendStatusMessage(msg);
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -62,18 +61,18 @@ export function getSubkeySize(keySize) {
|
|||
1024: 1024,
|
||||
2048: 1024,
|
||||
4096: 2048,
|
||||
256: 256,
|
||||
384: 256,
|
||||
256: 256,
|
||||
384: 256
|
||||
}[keySize];
|
||||
}
|
||||
|
||||
/**
|
||||
* Import private key and unlock if necessary
|
||||
*
|
||||
* @param {string} privateKey
|
||||
* @param {string} [passphrase]
|
||||
* @returns {Object}
|
||||
*/
|
||||
* Import private key and unlock if necessary
|
||||
*
|
||||
* @param {string} privateKey
|
||||
* @param {string} [passphrase]
|
||||
* @returns {Object}
|
||||
*/
|
||||
export async function importPrivateKey(privateKey, passphrase) {
|
||||
try {
|
||||
const key = await promisify(kbpgp.KeyManager.import_from_armored_pgp)({
|
||||
|
@ -103,7 +102,7 @@ export async function importPrivateKey(privateKey, passphrase) {
|
|||
* @param {string} publicKey
|
||||
* @returns {Object}
|
||||
*/
|
||||
export async function importPublicKey (publicKey) {
|
||||
export async function importPublicKey(publicKey) {
|
||||
try {
|
||||
const key = await promisify(kbpgp.KeyManager.import_from_armored_pgp)({
|
||||
armored: publicKey,
|
||||
|
|
|
@ -13,7 +13,6 @@ import protobuf from "protobufjs";
|
|||
* @license Apache-2.0
|
||||
*/
|
||||
class Protobuf {
|
||||
|
||||
/**
|
||||
* Protobuf constructor
|
||||
*
|
||||
|
@ -140,10 +139,10 @@ class Protobuf {
|
|||
static updateMainMessageName() {
|
||||
const messageNames = [];
|
||||
const fieldTypes = [];
|
||||
this.parsedProto.root.nestedArray.forEach(block => {
|
||||
this.parsedProto.root.nestedArray.forEach((block) => {
|
||||
if (block instanceof protobuf.Type) {
|
||||
messageNames.push(block.name);
|
||||
this.parsedProto.root.nested[block.name].fieldsArray.forEach(field => {
|
||||
this.parsedProto.root.nested[block.name].fieldsArray.forEach((field) => {
|
||||
fieldTypes.push(field.type);
|
||||
});
|
||||
}
|
||||
|
@ -195,7 +194,6 @@ class Protobuf {
|
|||
} else {
|
||||
return packageDecode;
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
if (message) {
|
||||
throw new Error("Input " + error);
|
||||
|
@ -216,7 +214,14 @@ class Protobuf {
|
|||
if (block instanceof protobuf.Type) {
|
||||
for (const [fieldName, fieldData] of Object.entries(block.fields)) {
|
||||
schemaRoot.nested[block.name].remove(block.fields[fieldName]);
|
||||
schemaRoot.nested[block.name].add(new protobuf.Field(`${fieldName} (${fieldData.type})`, fieldData.id, fieldData.type, fieldData.rule));
|
||||
schemaRoot.nested[block.name].add(
|
||||
new protobuf.Field(
|
||||
`${fieldName} (${fieldData.type})`,
|
||||
fieldData.id,
|
||||
fieldData.type,
|
||||
fieldData.rule
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -244,7 +249,7 @@ class Protobuf {
|
|||
if (Array.isArray(value)) {
|
||||
const fieldInstances = [];
|
||||
for (const instance of Object.keys(value)) {
|
||||
if (typeof(value[instance]) !== "string") {
|
||||
if (typeof value[instance] !== "string") {
|
||||
fieldInstances.push(this.showRawTypes(value[instance], fieldType));
|
||||
} else {
|
||||
fieldInstances.push(value[instance]);
|
||||
|
@ -252,12 +257,12 @@ class Protobuf {
|
|||
}
|
||||
outputFieldValue = fieldInstances;
|
||||
|
||||
// Single submessage
|
||||
// Single submessage
|
||||
} else {
|
||||
outputFieldValue = this.showRawTypes(value, fieldType);
|
||||
}
|
||||
|
||||
// Non-submessage field
|
||||
// Non-submessage field
|
||||
} else {
|
||||
outputFieldType = fieldType;
|
||||
outputFieldValue = value;
|
||||
|
@ -281,7 +286,7 @@ class Protobuf {
|
|||
// Define message data using raw decode output and schema
|
||||
const schemaFieldProperties = {};
|
||||
const schemaFieldNames = Object.keys(schemaMessage.fields);
|
||||
schemaFieldNames.forEach(field => schemaFieldProperties[schemaMessage.fields[field].id] = field);
|
||||
schemaFieldNames.forEach((field) => (schemaFieldProperties[schemaMessage.fields[field].id] = field));
|
||||
|
||||
// Loop over each field present in the raw decode output
|
||||
for (const fieldName in rawDecodedMessage) {
|
||||
|
@ -314,9 +319,9 @@ class Protobuf {
|
|||
|
||||
// Squash multiple submessage instances into one submessage
|
||||
if (Array.isArray(rawSubMessages)) {
|
||||
rawSubMessages.forEach(subMessageInstance => {
|
||||
rawSubMessages.forEach((subMessageInstance) => {
|
||||
const instanceFields = Object.entries(subMessageInstance);
|
||||
instanceFields.forEach(subField => {
|
||||
instanceFields.forEach((subField) => {
|
||||
rawDecodedSubMessage[subField[0]] = subField[1];
|
||||
});
|
||||
});
|
||||
|
@ -327,7 +332,8 @@ class Protobuf {
|
|||
// Treat submessage as own message and compare its fields
|
||||
rawDecodedSubMessage = Protobuf.compareFields(rawDecodedSubMessage, schemaSubMessage);
|
||||
if (Object.entries(rawDecodedSubMessage).length !== 0) {
|
||||
rawDecodedMessage[`${schemaFieldName} (${subMessageType}) has missing fields`] = rawDecodedSubMessage;
|
||||
rawDecodedMessage[`${schemaFieldName} (${subMessageType}) has missing fields`]
|
||||
= rawDecodedSubMessage;
|
||||
}
|
||||
}
|
||||
delete rawDecodedMessage[fieldName];
|
||||
|
@ -392,11 +398,11 @@ class Protobuf {
|
|||
// Get the field key/values
|
||||
const key = field.key;
|
||||
const value = field.value;
|
||||
object[key] = Object.prototype.hasOwnProperty.call(object, key) ?
|
||||
object[key] instanceof Array ?
|
||||
object[key].concat([value]) :
|
||||
[object[key], value] :
|
||||
value;
|
||||
object[key] = Object.prototype.hasOwnProperty.call(object, key)
|
||||
? object[key] instanceof Array
|
||||
? object[key].concat([value])
|
||||
: [object[key], value]
|
||||
: value;
|
||||
return object;
|
||||
}
|
||||
|
||||
|
@ -412,7 +418,7 @@ class Protobuf {
|
|||
const type = header.type;
|
||||
const key = header.key;
|
||||
|
||||
if (typeof(this.fieldTypes[key]) !== "object") {
|
||||
if (typeof this.fieldTypes[key] !== "object") {
|
||||
this.fieldTypes[key] = type;
|
||||
}
|
||||
|
||||
|
@ -472,11 +478,12 @@ class Protobuf {
|
|||
let shift = -3;
|
||||
let fieldNumber = 0;
|
||||
do {
|
||||
fieldNumber += shift < 28 ?
|
||||
shift === -3 ?
|
||||
(this.data[this.offset] & this.NUMBER) >> -shift :
|
||||
(this.data[this.offset] & this.VALUE) << shift :
|
||||
(this.data[this.offset] & this.VALUE) * Math.pow(2, shift);
|
||||
fieldNumber
|
||||
+= shift < 28
|
||||
? shift === -3
|
||||
? (this.data[this.offset] & this.NUMBER) >> -shift
|
||||
: (this.data[this.offset] & this.VALUE) << shift
|
||||
: (this.data[this.offset] & this.VALUE) * Math.pow(2, shift);
|
||||
shift += 7;
|
||||
} while ((this.data[this.offset++] & this.MSB) === this.MSB);
|
||||
return fieldNumber;
|
||||
|
@ -495,9 +502,10 @@ class Protobuf {
|
|||
let shift = 0;
|
||||
// Keep reading while upper bit set
|
||||
do {
|
||||
value += shift < 28 ?
|
||||
(this.data[this.offset] & this.VALUE) << shift :
|
||||
(this.data[this.offset] & this.VALUE) * Math.pow(2, shift);
|
||||
value
|
||||
+= shift < 28
|
||||
? (this.data[this.offset] & this.VALUE) << shift
|
||||
: (this.data[this.offset] & this.VALUE) * Math.pow(2, shift);
|
||||
shift += 7;
|
||||
} while ((this.data[this.offset++] & this.MSB) === this.MSB);
|
||||
return value;
|
||||
|
@ -511,8 +519,16 @@ class Protobuf {
|
|||
*/
|
||||
_uint64() {
|
||||
// Read off a Uint64 with little-endian
|
||||
const lowerHalf = this.data[this.offset++] + (this.data[this.offset++] * 0x100) + (this.data[this.offset++] * 0x10000) + this.data[this.offset++] * 0x1000000;
|
||||
const upperHalf = this.data[this.offset++] + (this.data[this.offset++] * 0x100) + (this.data[this.offset++] * 0x10000) + this.data[this.offset++] * 0x1000000;
|
||||
const lowerHalf
|
||||
= this.data[this.offset++]
|
||||
+ this.data[this.offset++] * 0x100
|
||||
+ this.data[this.offset++] * 0x10000
|
||||
+ this.data[this.offset++] * 0x1000000;
|
||||
const upperHalf
|
||||
= this.data[this.offset++]
|
||||
+ this.data[this.offset++] * 0x100
|
||||
+ this.data[this.offset++] * 0x10000
|
||||
+ this.data[this.offset++] * 0x1000000;
|
||||
return upperHalf * 0x100000000 + lowerHalf;
|
||||
}
|
||||
|
||||
|
@ -533,8 +549,7 @@ class Protobuf {
|
|||
field = pbObject._parse();
|
||||
|
||||
// Set field types object
|
||||
this.fieldTypes[fieldNum] = {...this.fieldTypes[fieldNum], ...pbObject.fieldTypes};
|
||||
|
||||
this.fieldTypes[fieldNum] = { ...this.fieldTypes[fieldNum], ...pbObject.fieldTypes };
|
||||
} catch (err) {
|
||||
// Otherwise treat as bytes
|
||||
field = Utils.byteArrayToChars(fieldBytes);
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
*/
|
||||
|
||||
import BigNumber from "bignumber.js";
|
||||
import {toHexFast} from "../lib/Hex.mjs";
|
||||
import { toHexFast } from "../lib/Hex.mjs";
|
||||
|
||||
/**
|
||||
* Recursively displays a JSON object as an HTML table
|
||||
|
@ -15,7 +15,7 @@ import {toHexFast} from "../lib/Hex.mjs";
|
|||
* @param {Object} obj
|
||||
* @returns string
|
||||
*/
|
||||
export function objToTable(obj, nested=false) {
|
||||
export function objToTable(obj, nested = false) {
|
||||
let html = `<table
|
||||
class='table table-sm table-nonfluid ${nested ? "mb-0 table-borderless" : "table-bordered"}'
|
||||
style='table-layout: fixed; ${nested ? "margin: -1px !important;" : ""}'>`;
|
||||
|
@ -27,10 +27,8 @@ export function objToTable(obj, nested=false) {
|
|||
|
||||
for (const key in obj) {
|
||||
html += `<tr><td style='word-wrap: break-word'>${key}</td>`;
|
||||
if (typeof obj[key] === "object")
|
||||
html += `<td style='padding: 0'>${objToTable(obj[key], true)}</td>`;
|
||||
else
|
||||
html += `<td>${obj[key]}</td>`;
|
||||
if (typeof obj[key] === "object") html += `<td style='padding: 0'>${objToTable(obj[key], true)}</td>`;
|
||||
else html += `<td>${obj[key]}</td>`;
|
||||
html += "</tr>";
|
||||
}
|
||||
html += "</table>";
|
||||
|
|
|
@ -35,7 +35,6 @@ export function formatDnObj(dnObj, indent) {
|
|||
return output.slice(0, -1);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Formats byte strings by adding line breaks and delimiters.
|
||||
*
|
||||
|
@ -58,5 +57,5 @@ export function formatByteStr(byteStr, length, indent) {
|
|||
}
|
||||
}
|
||||
|
||||
return output.slice(0, output.length-1);
|
||||
return output.slice(0, output.length - 1);
|
||||
}
|
||||
|
|
|
@ -30,7 +30,7 @@ export async function parseQrCode(input, normalise) {
|
|||
try {
|
||||
if (normalise) {
|
||||
image.rgba(false);
|
||||
image.background(0xFFFFFFFF);
|
||||
image.background(0xffffffff);
|
||||
image.normalize();
|
||||
image.greyscale();
|
||||
image = await image.getBufferAsync(jimp.MIME_JPEG);
|
||||
|
|
|
@ -13,5 +13,5 @@ export const MD_ALGORITHMS = {
|
|||
"MD5": forge.md.md5,
|
||||
"SHA-256": forge.md.sha256,
|
||||
"SHA-384": forge.md.sha384,
|
||||
"SHA-512": forge.md.sha512,
|
||||
"SHA-512": forge.md.sha512
|
||||
};
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
* @todo Support for UTF16
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Runs rotation operations across the input data.
|
||||
*
|
||||
|
@ -29,7 +28,6 @@ export function rot(data, amount, algo) {
|
|||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Rotate right bitwise op.
|
||||
*
|
||||
|
@ -49,10 +47,9 @@ export function rotr(b) {
|
|||
*/
|
||||
export function rotl(b) {
|
||||
const bit = (b >> 7) & 1;
|
||||
return ((b << 1) | bit) & 0xFF;
|
||||
return ((b << 1) | bit) & 0xff;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Rotates a byte array to the right by a specific amount as a whole, so that bits are wrapped
|
||||
* from the end of the array to the beginning.
|
||||
|
@ -70,14 +67,13 @@ export function rotrCarry(data, amount) {
|
|||
for (let i = 0; i < data.length; i++) {
|
||||
const oldByte = data[i] >>> 0;
|
||||
newByte = (oldByte >> amount) | carryBits;
|
||||
carryBits = (oldByte & (Math.pow(2, amount)-1)) << (8-amount);
|
||||
carryBits = (oldByte & (Math.pow(2, amount) - 1)) << (8 - amount);
|
||||
result.push(newByte);
|
||||
}
|
||||
result[0] |= carryBits;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Rotates a byte array to the left by a specific amount as a whole, so that bits are wrapped
|
||||
* from the beginning of the array to the end.
|
||||
|
@ -92,12 +88,12 @@ export function rotlCarry(data, amount) {
|
|||
newByte;
|
||||
|
||||
amount = amount % 8;
|
||||
for (let i = data.length-1; i >= 0; i--) {
|
||||
for (let i = data.length - 1; i >= 0; i--) {
|
||||
const oldByte = data[i];
|
||||
newByte = ((oldByte << amount) | carryBits) & 0xFF;
|
||||
carryBits = (oldByte >> (8-amount)) & (Math.pow(2, amount)-1);
|
||||
result[i] = (newByte);
|
||||
newByte = ((oldByte << amount) | carryBits) & 0xff;
|
||||
carryBits = (oldByte >> (8 - amount)) & (Math.pow(2, amount) - 1);
|
||||
result[i] = newByte;
|
||||
}
|
||||
result[data.length-1] = result[data.length-1] | carryBits;
|
||||
result[data.length - 1] = result[data.length - 1] | carryBits;
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -10,27 +10,27 @@
|
|||
* A set of randomised example SIGABA cipher/control rotors (these rotors are interchangeable). Cipher and control rotors can be referred to as C and R rotors respectively.
|
||||
*/
|
||||
export const CR_ROTORS = [
|
||||
{name: "Example 1", value: "SRGWANHPJZFXVIDQCEUKBYOLMT"},
|
||||
{name: "Example 2", value: "THQEFSAZVKJYULBODCPXNIMWRG"},
|
||||
{name: "Example 3", value: "XDTUYLEVFNQZBPOGIRCSMHWKAJ"},
|
||||
{name: "Example 4", value: "LOHDMCWUPSTNGVXYFJREQIKBZA"},
|
||||
{name: "Example 5", value: "ERXWNZQIJYLVOFUMSGHTCKPBDA"},
|
||||
{name: "Example 6", value: "FQECYHJIOUMDZVPSLKRTGWXBAN"},
|
||||
{name: "Example 7", value: "TBYIUMKZDJSOPEWXVANHLCFQGR"},
|
||||
{name: "Example 8", value: "QZUPDTFNYIAOMLEBWJXCGHKRSV"},
|
||||
{name: "Example 9", value: "CZWNHEMPOVXLKRSIDGJFYBTQAU"},
|
||||
{name: "Example 10", value: "ENPXJVKYQBFZTICAGMOHWRLDUS"}
|
||||
{ name: "Example 1", value: "SRGWANHPJZFXVIDQCEUKBYOLMT" },
|
||||
{ name: "Example 2", value: "THQEFSAZVKJYULBODCPXNIMWRG" },
|
||||
{ name: "Example 3", value: "XDTUYLEVFNQZBPOGIRCSMHWKAJ" },
|
||||
{ name: "Example 4", value: "LOHDMCWUPSTNGVXYFJREQIKBZA" },
|
||||
{ name: "Example 5", value: "ERXWNZQIJYLVOFUMSGHTCKPBDA" },
|
||||
{ name: "Example 6", value: "FQECYHJIOUMDZVPSLKRTGWXBAN" },
|
||||
{ name: "Example 7", value: "TBYIUMKZDJSOPEWXVANHLCFQGR" },
|
||||
{ name: "Example 8", value: "QZUPDTFNYIAOMLEBWJXCGHKRSV" },
|
||||
{ name: "Example 9", value: "CZWNHEMPOVXLKRSIDGJFYBTQAU" },
|
||||
{ name: "Example 10", value: "ENPXJVKYQBFZTICAGMOHWRLDUS" }
|
||||
];
|
||||
|
||||
/**
|
||||
* A set of randomised example SIGABA index rotors (may be referred to as I rotors).
|
||||
*/
|
||||
export const I_ROTORS = [
|
||||
{name: "Example 1", value: "6201348957"},
|
||||
{name: "Example 2", value: "6147253089"},
|
||||
{name: "Example 3", value: "8239647510"},
|
||||
{name: "Example 4", value: "7194835260"},
|
||||
{name: "Example 5", value: "4873205916"}
|
||||
{ name: "Example 1", value: "6201348957" },
|
||||
{ name: "Example 2", value: "6147253089" },
|
||||
{ name: "Example 3", value: "8239647510" },
|
||||
{ name: "Example 4", value: "7194835260" },
|
||||
{ name: "Example 5", value: "4873205916" }
|
||||
];
|
||||
|
||||
export const NUMBERS = "0123456789".split("");
|
||||
|
@ -43,8 +43,8 @@ export const NUMBERS = "0123456789".split("");
|
|||
*/
|
||||
export function convToUpperCase(letter) {
|
||||
const charCode = letter.charCodeAt();
|
||||
if (97<=charCode && charCode<=122) {
|
||||
return String.fromCharCode(charCode-32);
|
||||
if (97 <= charCode && charCode <= 122) {
|
||||
return String.fromCharCode(charCode - 32);
|
||||
}
|
||||
return letter;
|
||||
}
|
||||
|
@ -53,7 +53,6 @@ export function convToUpperCase(letter) {
|
|||
* The SIGABA machine consisting of the 3 rotor banks: cipher, control and index banks.
|
||||
*/
|
||||
export class SigabaMachine {
|
||||
|
||||
/**
|
||||
* SigabaMachine constructor
|
||||
*
|
||||
|
@ -137,14 +136,12 @@ export class SigabaMachine {
|
|||
}
|
||||
return plaintext;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* The cipher rotor bank consists of 5 cipher rotors in either a forward or reversed orientation.
|
||||
*/
|
||||
export class CipherBank {
|
||||
|
||||
/**
|
||||
* CipherBank constructor
|
||||
*
|
||||
|
@ -187,7 +184,7 @@ export class CipherBank {
|
|||
* @param {number[]} indexInputs - the inputs from the index rotors
|
||||
*/
|
||||
step(indexInputs) {
|
||||
const logicDict = {0: [0, 9], 1: [7, 8], 2: [5, 6], 3: [3, 4], 4: [1, 2]};
|
||||
const logicDict = { 0: [0, 9], 1: [7, 8], 2: [5, 6], 3: [3, 4], 4: [1, 2] };
|
||||
const rotorsToMove = [];
|
||||
for (const key in logicDict) {
|
||||
const item = logicDict[key];
|
||||
|
@ -202,14 +199,12 @@ export class CipherBank {
|
|||
rotor.step();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* The control rotor bank consists of 5 control rotors in either a forward or reversed orientation. Signals to the control rotor bank always go from right-to-left.
|
||||
*/
|
||||
export class ControlBank {
|
||||
|
||||
/**
|
||||
* ControlBank constructor. The rotors have been reversed as signals go from right-to-left through the control rotors.
|
||||
*
|
||||
|
@ -239,7 +234,7 @@ export class ControlBank {
|
|||
*/
|
||||
getOutputs() {
|
||||
const outputs = [this.crypt("F"), this.crypt("G"), this.crypt("H"), this.crypt("I")];
|
||||
const logicDict = {1: "B", 2: "C", 3: "DE", 4: "FGH", 5: "IJK", 6: "LMNO", 7: "PQRST", 8: "UVWXYZ", 9: "A"};
|
||||
const logicDict = { 1: "B", 2: "C", 3: "DE", 4: "FGH", 5: "IJK", 6: "LMNO", 7: "PQRST", 8: "UVWXYZ", 9: "A" };
|
||||
const numberOutputs = [];
|
||||
for (const key in logicDict) {
|
||||
const item = logicDict[key];
|
||||
|
@ -257,7 +252,9 @@ export class ControlBank {
|
|||
* Steps the control rotors. Only 3 of the control rotors step: one after every encryption, one after every 26, and one after every 26 squared.
|
||||
*/
|
||||
step() {
|
||||
const MRotor = this.rotors[1], FRotor = this.rotors[2], SRotor = this.rotors[3];
|
||||
const MRotor = this.rotors[1],
|
||||
FRotor = this.rotors[2],
|
||||
SRotor = this.rotors[3];
|
||||
// 14 is the offset of "O" from "A" - the next rotor steps once the previous rotor reaches "O"
|
||||
if (FRotor.state === 14) {
|
||||
if (MRotor.state === 14) {
|
||||
|
@ -278,14 +275,12 @@ export class ControlBank {
|
|||
this.step();
|
||||
return outputs;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* The index rotor bank consists of 5 index rotors all placed in the forwards orientation.
|
||||
*/
|
||||
export class IndexBank {
|
||||
|
||||
/**
|
||||
* IndexBank constructor
|
||||
*
|
||||
|
@ -321,14 +316,12 @@ export class IndexBank {
|
|||
}
|
||||
return outputs;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Rotor class
|
||||
*/
|
||||
export class Rotor {
|
||||
|
||||
/**
|
||||
* Rotor constructor
|
||||
*
|
||||
|
@ -350,12 +343,12 @@ export class Rotor {
|
|||
* @returns {number[]}
|
||||
*/
|
||||
getNumMapping(wireSetting, rev) {
|
||||
if (rev===false) {
|
||||
if (rev === false) {
|
||||
return wireSetting;
|
||||
} else {
|
||||
const length = wireSetting.length;
|
||||
const tempMapping = new Array(length);
|
||||
for (let i=0; i<length; i++) {
|
||||
for (let i = 0; i < length; i++) {
|
||||
tempMapping[wireSetting[i]] = i;
|
||||
}
|
||||
return tempMapping;
|
||||
|
@ -371,18 +364,18 @@ export class Rotor {
|
|||
getPosMapping(rev) {
|
||||
const length = this.numMapping.length;
|
||||
const posMapping = [];
|
||||
if (rev===false) {
|
||||
for (let i = this.state; i < this.state+length; i++) {
|
||||
let res = i%length;
|
||||
if (res<0) {
|
||||
if (rev === false) {
|
||||
for (let i = this.state; i < this.state + length; i++) {
|
||||
let res = i % length;
|
||||
if (res < 0) {
|
||||
res += length;
|
||||
}
|
||||
posMapping.push(res);
|
||||
}
|
||||
} else {
|
||||
for (let i = this.state; i > this.state-length; i--) {
|
||||
let res = i%length;
|
||||
if (res<0) {
|
||||
for (let i = this.state; i > this.state - length; i--) {
|
||||
let res = i % length;
|
||||
if (res < 0) {
|
||||
res += length;
|
||||
}
|
||||
posMapping.push(res);
|
||||
|
@ -418,14 +411,12 @@ export class Rotor {
|
|||
this.posMapping.splice(0, 0, lastNum);
|
||||
this.state = this.posMapping[0];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* A CRRotor is a cipher (C) or control (R) rotor. These rotors are identical and interchangeable. A C or R rotor consists of 26 contacts, one for each letter, and may be put into either a forwards of reversed orientation.
|
||||
*/
|
||||
export class CRRotor extends Rotor {
|
||||
|
||||
/**
|
||||
* CRRotor constructor
|
||||
*
|
||||
|
@ -433,7 +424,7 @@ export class CRRotor extends Rotor {
|
|||
* @param {char} key - initial state of rotor
|
||||
* @param {bool} rev - true if reversed, false if not
|
||||
*/
|
||||
constructor(wireSetting, key, rev=false) {
|
||||
constructor(wireSetting, key, rev = false) {
|
||||
wireSetting = wireSetting.split("").map(CRRotor.letterToNum);
|
||||
super(wireSetting, CRRotor.letterToNum(key), rev);
|
||||
}
|
||||
|
@ -445,7 +436,7 @@ export class CRRotor extends Rotor {
|
|||
* @returns {number}
|
||||
*/
|
||||
static letterToNum(letter) {
|
||||
return letter.charCodeAt()-65;
|
||||
return letter.charCodeAt() - 65;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -455,7 +446,7 @@ export class CRRotor extends Rotor {
|
|||
* @returns {char}
|
||||
*/
|
||||
static numToLetter(num) {
|
||||
return String.fromCharCode(num+65);
|
||||
return String.fromCharCode(num + 65);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -470,14 +461,12 @@ export class CRRotor extends Rotor {
|
|||
const outPos = this.cryptNum(inputPos, direction);
|
||||
return CRRotor.numToLetter(outPos);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* An IRotor is an index rotor, which consists of 10 contacts each numbered from 0 to 9. Unlike C and R rotors, they cannot be put in the reversed orientation. The index rotors do not step at any point during encryption or decryption.
|
||||
*/
|
||||
export class IRotor extends Rotor {
|
||||
|
||||
/**
|
||||
* IRotor constructor
|
||||
*
|
||||
|
@ -498,5 +487,4 @@ export class IRotor extends Rotor {
|
|||
crypt(inputPos) {
|
||||
return this.cryptNum(inputPos, "leftToRight");
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -23,34 +23,28 @@ const BLOCKSIZE = 16;
|
|||
|
||||
/** The S box, 256 8-bit values */
|
||||
const Sbox = [
|
||||
0xd6, 0x90, 0xe9, 0xfe, 0xcc, 0xe1, 0x3d, 0xb7, 0x16, 0xb6, 0x14, 0xc2, 0x28, 0xfb, 0x2c, 0x05,
|
||||
0x2b, 0x67, 0x9a, 0x76, 0x2a, 0xbe, 0x04, 0xc3, 0xaa, 0x44, 0x13, 0x26, 0x49, 0x86, 0x06, 0x99,
|
||||
0x9c, 0x42, 0x50, 0xf4, 0x91, 0xef, 0x98, 0x7a, 0x33, 0x54, 0x0b, 0x43, 0xed, 0xcf, 0xac, 0x62,
|
||||
0xe4, 0xb3, 0x1c, 0xa9, 0xc9, 0x08, 0xe8, 0x95, 0x80, 0xdf, 0x94, 0xfa, 0x75, 0x8f, 0x3f, 0xa6,
|
||||
0x47, 0x07, 0xa7, 0xfc, 0xf3, 0x73, 0x17, 0xba, 0x83, 0x59, 0x3c, 0x19, 0xe6, 0x85, 0x4f, 0xa8,
|
||||
0x68, 0x6b, 0x81, 0xb2, 0x71, 0x64, 0xda, 0x8b, 0xf8, 0xeb, 0x0f, 0x4b, 0x70, 0x56, 0x9d, 0x35,
|
||||
0x1e, 0x24, 0x0e, 0x5e, 0x63, 0x58, 0xd1, 0xa2, 0x25, 0x22, 0x7c, 0x3b, 0x01, 0x21, 0x78, 0x87,
|
||||
0xd4, 0x00, 0x46, 0x57, 0x9f, 0xd3, 0x27, 0x52, 0x4c, 0x36, 0x02, 0xe7, 0xa0, 0xc4, 0xc8, 0x9e,
|
||||
0xea, 0xbf, 0x8a, 0xd2, 0x40, 0xc7, 0x38, 0xb5, 0xa3, 0xf7, 0xf2, 0xce, 0xf9, 0x61, 0x15, 0xa1,
|
||||
0xe0, 0xae, 0x5d, 0xa4, 0x9b, 0x34, 0x1a, 0x55, 0xad, 0x93, 0x32, 0x30, 0xf5, 0x8c, 0xb1, 0xe3,
|
||||
0x1d, 0xf6, 0xe2, 0x2e, 0x82, 0x66, 0xca, 0x60, 0xc0, 0x29, 0x23, 0xab, 0x0d, 0x53, 0x4e, 0x6f,
|
||||
0xd5, 0xdb, 0x37, 0x45, 0xde, 0xfd, 0x8e, 0x2f, 0x03, 0xff, 0x6a, 0x72, 0x6d, 0x6c, 0x5b, 0x51,
|
||||
0x8d, 0x1b, 0xaf, 0x92, 0xbb, 0xdd, 0xbc, 0x7f, 0x11, 0xd9, 0x5c, 0x41, 0x1f, 0x10, 0x5a, 0xd8,
|
||||
0x0a, 0xc1, 0x31, 0x88, 0xa5, 0xcd, 0x7b, 0xbd, 0x2d, 0x74, 0xd0, 0x12, 0xb8, 0xe5, 0xb4, 0xb0,
|
||||
0x89, 0x69, 0x97, 0x4a, 0x0c, 0x96, 0x77, 0x7e, 0x65, 0xb9, 0xf1, 0x09, 0xc5, 0x6e, 0xc6, 0x84,
|
||||
0x18, 0xf0, 0x7d, 0xec, 0x3a, 0xdc, 0x4d, 0x20, 0x79, 0xee, 0x5f, 0x3e, 0xd7, 0xcb, 0x39, 0x48
|
||||
0xd6, 0x90, 0xe9, 0xfe, 0xcc, 0xe1, 0x3d, 0xb7, 0x16, 0xb6, 0x14, 0xc2, 0x28, 0xfb, 0x2c, 0x05, 0x2b, 0x67, 0x9a,
|
||||
0x76, 0x2a, 0xbe, 0x04, 0xc3, 0xaa, 0x44, 0x13, 0x26, 0x49, 0x86, 0x06, 0x99, 0x9c, 0x42, 0x50, 0xf4, 0x91, 0xef,
|
||||
0x98, 0x7a, 0x33, 0x54, 0x0b, 0x43, 0xed, 0xcf, 0xac, 0x62, 0xe4, 0xb3, 0x1c, 0xa9, 0xc9, 0x08, 0xe8, 0x95, 0x80,
|
||||
0xdf, 0x94, 0xfa, 0x75, 0x8f, 0x3f, 0xa6, 0x47, 0x07, 0xa7, 0xfc, 0xf3, 0x73, 0x17, 0xba, 0x83, 0x59, 0x3c, 0x19,
|
||||
0xe6, 0x85, 0x4f, 0xa8, 0x68, 0x6b, 0x81, 0xb2, 0x71, 0x64, 0xda, 0x8b, 0xf8, 0xeb, 0x0f, 0x4b, 0x70, 0x56, 0x9d,
|
||||
0x35, 0x1e, 0x24, 0x0e, 0x5e, 0x63, 0x58, 0xd1, 0xa2, 0x25, 0x22, 0x7c, 0x3b, 0x01, 0x21, 0x78, 0x87, 0xd4, 0x00,
|
||||
0x46, 0x57, 0x9f, 0xd3, 0x27, 0x52, 0x4c, 0x36, 0x02, 0xe7, 0xa0, 0xc4, 0xc8, 0x9e, 0xea, 0xbf, 0x8a, 0xd2, 0x40,
|
||||
0xc7, 0x38, 0xb5, 0xa3, 0xf7, 0xf2, 0xce, 0xf9, 0x61, 0x15, 0xa1, 0xe0, 0xae, 0x5d, 0xa4, 0x9b, 0x34, 0x1a, 0x55,
|
||||
0xad, 0x93, 0x32, 0x30, 0xf5, 0x8c, 0xb1, 0xe3, 0x1d, 0xf6, 0xe2, 0x2e, 0x82, 0x66, 0xca, 0x60, 0xc0, 0x29, 0x23,
|
||||
0xab, 0x0d, 0x53, 0x4e, 0x6f, 0xd5, 0xdb, 0x37, 0x45, 0xde, 0xfd, 0x8e, 0x2f, 0x03, 0xff, 0x6a, 0x72, 0x6d, 0x6c,
|
||||
0x5b, 0x51, 0x8d, 0x1b, 0xaf, 0x92, 0xbb, 0xdd, 0xbc, 0x7f, 0x11, 0xd9, 0x5c, 0x41, 0x1f, 0x10, 0x5a, 0xd8, 0x0a,
|
||||
0xc1, 0x31, 0x88, 0xa5, 0xcd, 0x7b, 0xbd, 0x2d, 0x74, 0xd0, 0x12, 0xb8, 0xe5, 0xb4, 0xb0, 0x89, 0x69, 0x97, 0x4a,
|
||||
0x0c, 0x96, 0x77, 0x7e, 0x65, 0xb9, 0xf1, 0x09, 0xc5, 0x6e, 0xc6, 0x84, 0x18, 0xf0, 0x7d, 0xec, 0x3a, 0xdc, 0x4d,
|
||||
0x20, 0x79, 0xee, 0x5f, 0x3e, 0xd7, 0xcb, 0x39, 0x48
|
||||
];
|
||||
|
||||
/** "Fixed parameter CK" used in key expansion */
|
||||
const CK = [
|
||||
0x00070e15, 0x1c232a31, 0x383f464d, 0x545b6269,
|
||||
0x70777e85, 0x8c939aa1, 0xa8afb6bd, 0xc4cbd2d9,
|
||||
0xe0e7eef5, 0xfc030a11, 0x181f262d, 0x343b4249,
|
||||
0x50575e65, 0x6c737a81, 0x888f969d, 0xa4abb2b9,
|
||||
0xc0c7ced5, 0xdce3eaf1, 0xf8ff060d, 0x141b2229,
|
||||
0x30373e45, 0x4c535a61, 0x686f767d, 0x848b9299,
|
||||
0xa0a7aeb5, 0xbcc3cad1, 0xd8dfe6ed, 0xf4fb0209,
|
||||
0x10171e25, 0x2c333a41, 0x484f565d, 0x646b7279
|
||||
0x00070e15, 0x1c232a31, 0x383f464d, 0x545b6269, 0x70777e85, 0x8c939aa1, 0xa8afb6bd, 0xc4cbd2d9, 0xe0e7eef5,
|
||||
0xfc030a11, 0x181f262d, 0x343b4249, 0x50575e65, 0x6c737a81, 0x888f969d, 0xa4abb2b9, 0xc0c7ced5, 0xdce3eaf1,
|
||||
0xf8ff060d, 0x141b2229, 0x30373e45, 0x4c535a61, 0x686f767d, 0x848b9299, 0xa0a7aeb5, 0xbcc3cad1, 0xd8dfe6ed,
|
||||
0xf4fb0209, 0x10171e25, 0x2c333a41, 0x484f565d, 0x646b7279
|
||||
];
|
||||
|
||||
/** "System parameter FK" */
|
||||
|
@ -73,8 +67,11 @@ function ROL(i, n) {
|
|||
*/
|
||||
function transformL(b) {
|
||||
/* Replace each of the 4 bytes in b with the value at its offset in the Sbox */
|
||||
b = (Sbox[(b >>> 24) & 0xFF] << 24) | (Sbox[(b >>> 16) & 0xFF] << 16) |
|
||||
(Sbox[(b >>> 8) & 0xFF] << 8) | Sbox[b & 0xFF];
|
||||
b
|
||||
= (Sbox[(b >>> 24) & 0xff] << 24)
|
||||
| (Sbox[(b >>> 16) & 0xff] << 16)
|
||||
| (Sbox[(b >>> 8) & 0xff] << 8)
|
||||
| Sbox[b & 0xff];
|
||||
/* circular rotate and xor */
|
||||
return b ^ ROL(b, 2) ^ ROL(b, 10) ^ ROL(b, 18) ^ ROL(b, 24);
|
||||
}
|
||||
|
@ -86,8 +83,11 @@ function transformL(b) {
|
|||
*/
|
||||
function transformLprime(b) {
|
||||
/* Replace each of the 4 bytes in b with the value at its offset in the Sbox */
|
||||
b = (Sbox[(b >>> 24) & 0xFF] << 24) | (Sbox[(b >>> 16) & 0xFF] << 16) |
|
||||
(Sbox[(b >>> 8) & 0xFF] << 8) | Sbox[b & 0xFF];
|
||||
b
|
||||
= (Sbox[(b >>> 24) & 0xff] << 24)
|
||||
| (Sbox[(b >>> 16) & 0xff] << 16)
|
||||
| (Sbox[(b >>> 8) & 0xff] << 8)
|
||||
| Sbox[b & 0xff];
|
||||
return b ^ ROL(b, 13) ^ ROL(b, 23); /* circular rotate and XOR */
|
||||
}
|
||||
|
||||
|
@ -95,7 +95,7 @@ function transformLprime(b) {
|
|||
* Initialize the round key
|
||||
*/
|
||||
function initSM4RoundKey(rawkey) {
|
||||
const K = rawkey.map((a, i) => a ^ FK[i]); /* K = rawkey ^ FK */
|
||||
const K = rawkey.map((a, i) => a ^ FK[i]); /* K = rawkey ^ FK */
|
||||
const roundKey = [];
|
||||
for (let i = 0; i < 32; i++)
|
||||
roundKey[i] = K[i + 4] = K[i] ^ transformLprime(K[i + 1] ^ K[i + 2] ^ K[i + 3] ^ CK[i]);
|
||||
|
@ -110,8 +110,7 @@ function initSM4RoundKey(rawkey) {
|
|||
* @returns {byteArray} - The cipher text.
|
||||
*/
|
||||
function encryptBlockSM4(X, roundKey) {
|
||||
for (let i = 0; i < NROUNDS; i++)
|
||||
X[i + 4] = X[i] ^ transformL(X[i + 1] ^ X[i + 2] ^ X[i + 3] ^ roundKey[i]);
|
||||
for (let i = 0; i < NROUNDS; i++) X[i + 4] = X[i] ^ transformL(X[i + 1] ^ X[i + 2] ^ X[i + 3] ^ roundKey[i]);
|
||||
return [X[35], X[34], X[33], X[32]];
|
||||
}
|
||||
|
||||
|
@ -122,7 +121,7 @@ function encryptBlockSM4(X, roundKey) {
|
|||
* @param {byteArray} bArray - the array of bytes
|
||||
* @param {integer} offset - starting offset in the array; 15 bytes must follow it.
|
||||
*/
|
||||
function bytesToInts(bArray, offs=0) {
|
||||
function bytesToInts(bArray, offs = 0) {
|
||||
let offset = offs;
|
||||
const A = (bArray[offset] << 24) | (bArray[offset + 1] << 16) | (bArray[offset + 2] << 8) | bArray[offset + 3];
|
||||
offset += 4;
|
||||
|
@ -141,10 +140,10 @@ function bytesToInts(bArray, offs=0) {
|
|||
function intsToBytes(ints) {
|
||||
const bArr = [];
|
||||
for (let i = 0; i < ints.length; i++) {
|
||||
bArr.push((ints[i] >> 24) & 0xFF);
|
||||
bArr.push((ints[i] >> 16) & 0xFF);
|
||||
bArr.push((ints[i] >> 8) & 0xFF);
|
||||
bArr.push(ints[i] & 0xFF);
|
||||
bArr.push((ints[i] >> 24) & 0xff);
|
||||
bArr.push((ints[i] >> 16) & 0xff);
|
||||
bArr.push((ints[i] >> 8) & 0xff);
|
||||
bArr.push(ints[i] & 0xff);
|
||||
}
|
||||
return bArr;
|
||||
}
|
||||
|
@ -159,25 +158,22 @@ function intsToBytes(ints) {
|
|||
* @param {boolean} noPadding - Don't add PKCS#7 padding if set.
|
||||
* @returns {byteArray} - The cipher text.
|
||||
*/
|
||||
export function encryptSM4(message, key, iv, mode="ECB", noPadding=false) {
|
||||
export function encryptSM4(message, key, iv, mode = "ECB", noPadding = false) {
|
||||
const messageLength = message.length;
|
||||
if (messageLength === 0)
|
||||
return [];
|
||||
if (messageLength === 0) return [];
|
||||
const roundKey = initSM4RoundKey(bytesToInts(key, 0));
|
||||
|
||||
/* Pad with PKCS#7 if requested for ECB/CBC else add zeroes (which are sliced off at the end) */
|
||||
let padByte = 0;
|
||||
let nPadding = 16 - (message.length & 0xF);
|
||||
let nPadding = 16 - (message.length & 0xf);
|
||||
if (mode === "ECB" || mode === "CBC") {
|
||||
if (noPadding) {
|
||||
if (nPadding !== 16)
|
||||
throw new OperationError(`No padding requested in ${mode} mode but input is not a 16-byte multiple.`);
|
||||
nPadding = 0;
|
||||
} else
|
||||
padByte = nPadding;
|
||||
} else padByte = nPadding;
|
||||
}
|
||||
for (let i = 0; i < nPadding; i++)
|
||||
message.push(padByte);
|
||||
for (let i = 0; i < nPadding; i++) message.push(padByte);
|
||||
|
||||
const cipherText = [];
|
||||
switch (mode) {
|
||||
|
@ -189,8 +185,10 @@ export function encryptSM4(message, key, iv, mode="ECB", noPadding=false) {
|
|||
iv = bytesToInts(iv, 0);
|
||||
for (let i = 0; i < message.length; i += BLOCKSIZE) {
|
||||
const block = bytesToInts(message, i);
|
||||
block[0] ^= iv[0]; block[1] ^= iv[1];
|
||||
block[2] ^= iv[2]; block[3] ^= iv[3];
|
||||
block[0] ^= iv[0];
|
||||
block[1] ^= iv[1];
|
||||
block[2] ^= iv[2];
|
||||
block[3] ^= iv[3];
|
||||
iv = encryptBlockSM4(block, roundKey);
|
||||
Array.prototype.push.apply(cipherText, intsToBytes(iv));
|
||||
}
|
||||
|
@ -200,8 +198,10 @@ export function encryptSM4(message, key, iv, mode="ECB", noPadding=false) {
|
|||
for (let i = 0; i < message.length; i += BLOCKSIZE) {
|
||||
iv = encryptBlockSM4(iv, roundKey);
|
||||
const block = bytesToInts(message, i);
|
||||
block[0] ^= iv[0]; block[1] ^= iv[1];
|
||||
block[2] ^= iv[2]; block[3] ^= iv[3];
|
||||
block[0] ^= iv[0];
|
||||
block[1] ^= iv[1];
|
||||
block[2] ^= iv[2];
|
||||
block[3] ^= iv[3];
|
||||
Array.prototype.push.apply(cipherText, intsToBytes(block));
|
||||
iv = block;
|
||||
}
|
||||
|
@ -211,8 +211,10 @@ export function encryptSM4(message, key, iv, mode="ECB", noPadding=false) {
|
|||
for (let i = 0; i < message.length; i += BLOCKSIZE) {
|
||||
iv = encryptBlockSM4(iv, roundKey);
|
||||
const block = bytesToInts(message, i);
|
||||
block[0] ^= iv[0]; block[1] ^= iv[1];
|
||||
block[2] ^= iv[2]; block[3] ^= iv[3];
|
||||
block[0] ^= iv[0];
|
||||
block[1] ^= iv[1];
|
||||
block[2] ^= iv[2];
|
||||
block[3] ^= iv[3];
|
||||
Array.prototype.push.apply(cipherText, intsToBytes(block));
|
||||
}
|
||||
break;
|
||||
|
@ -220,19 +222,20 @@ export function encryptSM4(message, key, iv, mode="ECB", noPadding=false) {
|
|||
iv = bytesToInts(iv, 0);
|
||||
for (let i = 0; i < message.length; i += BLOCKSIZE) {
|
||||
let iv2 = [...iv]; /* containing the IV + counter */
|
||||
iv2[3] += (i >> 4);/* Using a 32 bit counter here. 64 Gb encrypts should be enough for everyone. */
|
||||
iv2[3] += i >> 4; /* Using a 32 bit counter here. 64 Gb encrypts should be enough for everyone. */
|
||||
iv2 = encryptBlockSM4(iv2, roundKey);
|
||||
const block = bytesToInts(message, i);
|
||||
block[0] ^= iv2[0]; block[1] ^= iv2[1];
|
||||
block[2] ^= iv2[2]; block[3] ^= iv2[3];
|
||||
block[0] ^= iv2[0];
|
||||
block[1] ^= iv2[1];
|
||||
block[2] ^= iv2[2];
|
||||
block[3] ^= iv2[3];
|
||||
Array.prototype.push.apply(cipherText, intsToBytes(block));
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw new OperationError("Invalid block cipher mode: "+mode);
|
||||
throw new OperationError("Invalid block cipher mode: " + mode);
|
||||
}
|
||||
if (mode !== "ECB" && mode !== "CBC")
|
||||
return cipherText.slice(0, messageLength);
|
||||
if (mode !== "ECB" && mode !== "CBC") return cipherText.slice(0, messageLength);
|
||||
return cipherText;
|
||||
}
|
||||
|
||||
|
@ -246,34 +249,40 @@ export function encryptSM4(message, key, iv, mode="ECB", noPadding=false) {
|
|||
* @param {boolean] ignorePadding - If true, ignore padding issues in ECB/CBC mode.
|
||||
* @returns {byteArray} - The cipher text.
|
||||
*/
|
||||
export function decryptSM4(cipherText, key, iv, mode="ECB", ignorePadding=false) {
|
||||
export function decryptSM4(cipherText, key, iv, mode = "ECB", ignorePadding = false) {
|
||||
const originalLength = cipherText.length;
|
||||
if (originalLength === 0)
|
||||
return [];
|
||||
if (originalLength === 0) return [];
|
||||
let roundKey = initSM4RoundKey(bytesToInts(key, 0));
|
||||
|
||||
if (mode === "ECB" || mode === "CBC") {
|
||||
/* Init decryption key */
|
||||
roundKey = roundKey.reverse();
|
||||
if ((originalLength & 0xF) !== 0 && !ignorePadding)
|
||||
throw new OperationError(`With ECB or CBC modes, the input must be divisible into 16 byte blocks. (${cipherText.length & 0xF} bytes extra)`);
|
||||
} else { /* Pad dummy bytes for other modes, chop them off at the end */
|
||||
while ((cipherText.length & 0xF) !== 0)
|
||||
cipherText.push(0);
|
||||
if ((originalLength & 0xf) !== 0 && !ignorePadding)
|
||||
throw new OperationError(
|
||||
`With ECB or CBC modes, the input must be divisible into 16 byte blocks. (${cipherText.length & 0xf} bytes extra)`
|
||||
);
|
||||
} else {
|
||||
/* Pad dummy bytes for other modes, chop them off at the end */
|
||||
while ((cipherText.length & 0xf) !== 0) cipherText.push(0);
|
||||
}
|
||||
|
||||
const clearText = [];
|
||||
switch (mode) {
|
||||
case "ECB":
|
||||
for (let i = 0; i < cipherText.length; i += BLOCKSIZE)
|
||||
Array.prototype.push.apply(clearText, intsToBytes(encryptBlockSM4(bytesToInts(cipherText, i), roundKey)));
|
||||
Array.prototype.push.apply(
|
||||
clearText,
|
||||
intsToBytes(encryptBlockSM4(bytesToInts(cipherText, i), roundKey))
|
||||
);
|
||||
break;
|
||||
case "CBC":
|
||||
iv = bytesToInts(iv, 0);
|
||||
for (let i = 0; i < cipherText.length; i += BLOCKSIZE) {
|
||||
const block = encryptBlockSM4(bytesToInts(cipherText, i), roundKey);
|
||||
block[0] ^= iv[0]; block[1] ^= iv[1];
|
||||
block[2] ^= iv[2]; block[3] ^= iv[3];
|
||||
block[0] ^= iv[0];
|
||||
block[1] ^= iv[1];
|
||||
block[2] ^= iv[2];
|
||||
block[3] ^= iv[3];
|
||||
Array.prototype.push.apply(clearText, intsToBytes(block));
|
||||
iv = bytesToInts(cipherText, i);
|
||||
}
|
||||
|
@ -283,8 +292,10 @@ export function decryptSM4(cipherText, key, iv, mode="ECB", ignorePadding=false)
|
|||
for (let i = 0; i < cipherText.length; i += BLOCKSIZE) {
|
||||
iv = encryptBlockSM4(iv, roundKey);
|
||||
const block = bytesToInts(cipherText, i);
|
||||
block[0] ^= iv[0]; block[1] ^= iv[1];
|
||||
block[2] ^= iv[2]; block[3] ^= iv[3];
|
||||
block[0] ^= iv[0];
|
||||
block[1] ^= iv[1];
|
||||
block[2] ^= iv[2];
|
||||
block[3] ^= iv[3];
|
||||
Array.prototype.push.apply(clearText, intsToBytes(block));
|
||||
iv = bytesToInts(cipherText, i);
|
||||
}
|
||||
|
@ -294,8 +305,10 @@ export function decryptSM4(cipherText, key, iv, mode="ECB", ignorePadding=false)
|
|||
for (let i = 0; i < cipherText.length; i += BLOCKSIZE) {
|
||||
iv = encryptBlockSM4(iv, roundKey);
|
||||
const block = bytesToInts(cipherText, i);
|
||||
block[0] ^= iv[0]; block[1] ^= iv[1];
|
||||
block[2] ^= iv[2]; block[3] ^= iv[3];
|
||||
block[0] ^= iv[0];
|
||||
block[1] ^= iv[1];
|
||||
block[2] ^= iv[2];
|
||||
block[3] ^= iv[3];
|
||||
Array.prototype.push.apply(clearText, intsToBytes(block));
|
||||
}
|
||||
break;
|
||||
|
@ -303,11 +316,13 @@ export function decryptSM4(cipherText, key, iv, mode="ECB", ignorePadding=false)
|
|||
iv = bytesToInts(iv, 0);
|
||||
for (let i = 0; i < cipherText.length; i += BLOCKSIZE) {
|
||||
let iv2 = [...iv]; /* containing the IV + counter */
|
||||
iv2[3] += (i >> 4);/* Using a 32 bit counter here. 64 Gb encrypts should be enough for everyone. */
|
||||
iv2[3] += i >> 4; /* Using a 32 bit counter here. 64 Gb encrypts should be enough for everyone. */
|
||||
iv2 = encryptBlockSM4(iv2, roundKey);
|
||||
const block = bytesToInts(cipherText, i);
|
||||
block[0] ^= iv2[0]; block[1] ^= iv2[1];
|
||||
block[2] ^= iv2[2]; block[3] ^= iv2[3];
|
||||
block[0] ^= iv2[0];
|
||||
block[1] ^= iv2[1];
|
||||
block[2] ^= iv2[2];
|
||||
block[3] ^= iv2[3];
|
||||
Array.prototype.push.apply(clearText, intsToBytes(block));
|
||||
}
|
||||
break;
|
||||
|
@ -316,16 +331,12 @@ export function decryptSM4(cipherText, key, iv, mode="ECB", ignorePadding=false)
|
|||
}
|
||||
/* Check PKCS#7 padding */
|
||||
if (mode === "ECB" || mode === "CBC") {
|
||||
if (ignorePadding)
|
||||
return clearText;
|
||||
if (ignorePadding) return clearText;
|
||||
const padByte = clearText[clearText.length - 1];
|
||||
if (padByte > 16)
|
||||
throw new OperationError("Invalid PKCS#7 padding.");
|
||||
if (padByte > 16) throw new OperationError("Invalid PKCS#7 padding.");
|
||||
for (let i = 0; i < padByte; i++)
|
||||
if (clearText[clearText.length -i - 1] !== padByte)
|
||||
throw new OperationError("Invalid PKCS#7 padding.");
|
||||
if (clearText[clearText.length - i - 1] !== padByte) throw new OperationError("Invalid PKCS#7 padding.");
|
||||
return clearText.slice(0, clearText.length - padByte);
|
||||
}
|
||||
return clearText.slice(0, originalLength);
|
||||
}
|
||||
|
||||
|
|
|
@ -18,7 +18,6 @@ export function caseInsensitiveSort(a, b) {
|
|||
return a.toLowerCase().localeCompare(b.toLowerCase());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Comparison operation for sorting of IPv4 addresses.
|
||||
*
|
||||
|
@ -59,7 +58,8 @@ export function numericSort(a, b) {
|
|||
const ret = a_[i].localeCompare(b_[i]); // Compare strings
|
||||
if (ret !== 0) return ret;
|
||||
}
|
||||
if (!isNaN(a_[i]) && !isNaN(b_[i])) { // Compare numbers
|
||||
if (!isNaN(a_[i]) && !isNaN(b_[i])) {
|
||||
// Compare numbers
|
||||
if (a_[i] - b_[i] !== 0) return a_[i] - b_[i];
|
||||
}
|
||||
}
|
||||
|
@ -79,12 +79,12 @@ export function hexadecimalSort(a, b) {
|
|||
let a_ = a.split(/([^\da-f]+)/i),
|
||||
b_ = b.split(/([^\da-f]+)/i);
|
||||
|
||||
a_ = a_.map(v => {
|
||||
a_ = a_.map((v) => {
|
||||
const t = parseInt(v, 16);
|
||||
return isNaN(t) ? v : t;
|
||||
});
|
||||
|
||||
b_ = b_.map(v => {
|
||||
b_ = b_.map((v) => {
|
||||
const t = parseInt(v, 16);
|
||||
return isNaN(t) ? v : t;
|
||||
});
|
||||
|
@ -96,7 +96,8 @@ export function hexadecimalSort(a, b) {
|
|||
const ret = a_[i].localeCompare(b_[i]); // Compare strings
|
||||
if (ret !== 0) return ret;
|
||||
}
|
||||
if (!isNaN(a_[i]) && !isNaN(b_[i])) { // Compare numbers
|
||||
if (!isNaN(a_[i]) && !isNaN(b_[i])) {
|
||||
// Compare numbers
|
||||
if (a_[i] - b_[i] !== 0) return a_[i] - b_[i];
|
||||
}
|
||||
}
|
||||
|
@ -114,4 +115,3 @@ export function hexadecimalSort(a, b) {
|
|||
export function lengthSort(a, b) {
|
||||
return a.length - b.length;
|
||||
}
|
||||
|
||||
|
|
|
@ -13,7 +13,6 @@
|
|||
* as various data types.
|
||||
*/
|
||||
export default class Stream {
|
||||
|
||||
/**
|
||||
* Stream constructor.
|
||||
*
|
||||
|
@ -32,12 +31,10 @@ export default class Stream {
|
|||
* @param {number} [numBytes=null]
|
||||
* @returns {Uint8Array}
|
||||
*/
|
||||
getBytes(numBytes=null) {
|
||||
getBytes(numBytes = null) {
|
||||
if (this.position > this.length) return undefined;
|
||||
|
||||
const newPosition = numBytes !== null ?
|
||||
this.position + numBytes :
|
||||
this.length;
|
||||
const newPosition = numBytes !== null ? this.position + numBytes : this.length;
|
||||
const bytes = this.bytes.slice(this.position, newPosition);
|
||||
this.position = newPosition;
|
||||
this.bitPos = 0;
|
||||
|
@ -51,7 +48,7 @@ export default class Stream {
|
|||
* @param {number} [numBytes=-1]
|
||||
* @returns {string}
|
||||
*/
|
||||
readString(numBytes=-1) {
|
||||
readString(numBytes = -1) {
|
||||
if (this.position > this.length) return undefined;
|
||||
|
||||
if (numBytes === -1) numBytes = this.length - this.position;
|
||||
|
@ -74,7 +71,7 @@ export default class Stream {
|
|||
* @param {string} [endianness="be"]
|
||||
* @returns {number}
|
||||
*/
|
||||
readInt(numBytes, endianness="be") {
|
||||
readInt(numBytes, endianness = "be") {
|
||||
if (this.position > this.length) return undefined;
|
||||
|
||||
let val = 0;
|
||||
|
@ -101,7 +98,7 @@ export default class Stream {
|
|||
* @param {string} [endianness="be"]
|
||||
* @returns {number}
|
||||
*/
|
||||
readBits(numBits, endianness="be") {
|
||||
readBits(numBits, endianness = "be") {
|
||||
if (this.position > this.length) return undefined;
|
||||
|
||||
let bitBuf = 0,
|
||||
|
@ -115,20 +112,16 @@ export default class Stream {
|
|||
|
||||
// Not enough bits yet
|
||||
while (bitBufLen < numBits) {
|
||||
if (endianness === "be")
|
||||
bitBuf = (bitBuf << bitBufLen) | this.bytes[this.position++];
|
||||
else
|
||||
bitBuf |= this.bytes[this.position++] << bitBufLen;
|
||||
if (endianness === "be") bitBuf = (bitBuf << bitBufLen) | this.bytes[this.position++];
|
||||
else bitBuf |= this.bytes[this.position++] << bitBufLen;
|
||||
bitBufLen += 8;
|
||||
}
|
||||
|
||||
// Reverse back to numBits
|
||||
if (bitBufLen > numBits) {
|
||||
const excess = bitBufLen - numBits;
|
||||
if (endianness === "be")
|
||||
bitBuf >>>= excess;
|
||||
else
|
||||
bitBuf &= (1 << numBits) - 1;
|
||||
if (endianness === "be") bitBuf >>>= excess;
|
||||
else bitBuf &= (1 << numBits) - 1;
|
||||
bitBufLen -= excess;
|
||||
this.position--;
|
||||
this.bitPos = 8 - excess;
|
||||
|
@ -143,9 +136,7 @@ export default class Stream {
|
|||
* @returns {number} The bit mask
|
||||
*/
|
||||
function bitMask(bitPos) {
|
||||
return endianness === "be" ?
|
||||
(1 << (8 - bitPos)) - 1 :
|
||||
256 - (1 << bitPos);
|
||||
return endianness === "be" ? (1 << (8 - bitPos)) - 1 : 256 - (1 << bitPos);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -184,7 +175,7 @@ export default class Stream {
|
|||
}
|
||||
|
||||
const length = val.length;
|
||||
const initial = val[length-1];
|
||||
const initial = val[length - 1];
|
||||
this.position = length;
|
||||
|
||||
// Get the skip table.
|
||||
|
@ -193,12 +184,12 @@ export default class Stream {
|
|||
|
||||
while (this.position < this.length) {
|
||||
// Until we hit the final element of val in the stream.
|
||||
while ((this.position < this.length) && (this.bytes[this.position++] !== initial));
|
||||
while (this.position < this.length && this.bytes[this.position++] !== initial);
|
||||
|
||||
found = true;
|
||||
|
||||
// Loop through the elements comparing them to val.
|
||||
for (let x = length-1; x >= 0; x--) {
|
||||
for (let x = length - 1; x >= 0; x--) {
|
||||
if (this.bytes[this.position - length + x] !== val[x]) {
|
||||
found = false;
|
||||
|
||||
|
@ -214,7 +205,6 @@ export default class Stream {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Consume bytes if they match the supplied value.
|
||||
*
|
||||
|
@ -319,9 +309,8 @@ export default class Stream {
|
|||
* @param {number} [finish=this.position]
|
||||
* @returns {Uint8Array}
|
||||
*/
|
||||
carve(start=0, finish=this.position) {
|
||||
carve(start = 0, finish = this.position) {
|
||||
if (this.bitPos > 0) finish++;
|
||||
return this.bytes.slice(start, finish);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -17,7 +17,6 @@ const defaults = {
|
|||
* TLVParser library
|
||||
*/
|
||||
export default class TLVParser {
|
||||
|
||||
/**
|
||||
* TLVParser constructor
|
||||
*
|
||||
|
|
|
@ -15,28 +15,45 @@ import Utils from "../Utils.mjs";
|
|||
* randomised.
|
||||
*/
|
||||
export const ROTORS = [
|
||||
{name: "Example 1", value: "MCYLPQUVRXGSAOWNBJEZDTFKHI<BFHNQUW"},
|
||||
{name: "Example 2", value: "KHWENRCBISXJQGOFMAPVYZDLTU<BFHNQUW"},
|
||||
{name: "Example 3", value: "BYPDZMGIKQCUSATREHOJNLFWXV<BFHNQUW"},
|
||||
{name: "Example 4", value: "ZANJCGDLVHIXOBRPMSWQUKFYET<BFHNQUW"},
|
||||
{name: "Example 5", value: "QXBGUTOVFCZPJIHSWERYNDAMLK<BFHNQUW"},
|
||||
{name: "Example 6", value: "BDCNWUEIQVFTSXALOGZJYMHKPR<BFHNQUW"},
|
||||
{name: "Example 7", value: "WJUKEIABMSGFTQZVCNPHORDXYL<BFHNQUW"},
|
||||
{name: "Example 8", value: "TNVCZXDIPFWQKHSJMAOYLEURGB<BFHNQUW"},
|
||||
{ name: "Example 1", value: "MCYLPQUVRXGSAOWNBJEZDTFKHI<BFHNQUW" },
|
||||
{ name: "Example 2", value: "KHWENRCBISXJQGOFMAPVYZDLTU<BFHNQUW" },
|
||||
{ name: "Example 3", value: "BYPDZMGIKQCUSATREHOJNLFWXV<BFHNQUW" },
|
||||
{ name: "Example 4", value: "ZANJCGDLVHIXOBRPMSWQUKFYET<BFHNQUW" },
|
||||
{ name: "Example 5", value: "QXBGUTOVFCZPJIHSWERYNDAMLK<BFHNQUW" },
|
||||
{ name: "Example 6", value: "BDCNWUEIQVFTSXALOGZJYMHKPR<BFHNQUW" },
|
||||
{ name: "Example 7", value: "WJUKEIABMSGFTQZVCNPHORDXYL<BFHNQUW" },
|
||||
{ name: "Example 8", value: "TNVCZXDIPFWQKHSJMAOYLEURGB<BFHNQUW" }
|
||||
];
|
||||
|
||||
/**
|
||||
* An example Typex reflector. Again, randomised.
|
||||
*/
|
||||
export const REFLECTORS = [
|
||||
{name: "Example", value: "AN BC FG IE KD LU MH OR TS VZ WQ XJ YP"},
|
||||
];
|
||||
export const REFLECTORS = [{ name: "Example", value: "AN BC FG IE KD LU MH OR TS VZ WQ XJ YP" }];
|
||||
|
||||
// Special character handling on Typex keyboard
|
||||
const KEYBOARD = {
|
||||
"Q": "1", "W": "2", "E": "3", "R": "4", "T": "5", "Y": "6", "U": "7", "I": "8", "O": "9", "P": "0",
|
||||
"A": "-", "S": "/", "D": "Z", "F": "%", "G": "X", "H": "£", "K": "(", "L": ")",
|
||||
"C": "V", "B": "'", "N": ",", "M": "."
|
||||
"Q": "1",
|
||||
"W": "2",
|
||||
"E": "3",
|
||||
"R": "4",
|
||||
"T": "5",
|
||||
"Y": "6",
|
||||
"U": "7",
|
||||
"I": "8",
|
||||
"O": "9",
|
||||
"P": "0",
|
||||
"A": "-",
|
||||
"S": "/",
|
||||
"D": "Z",
|
||||
"F": "%",
|
||||
"G": "X",
|
||||
"H": "£",
|
||||
"K": "(",
|
||||
"L": ")",
|
||||
"C": "V",
|
||||
"B": "'",
|
||||
"N": ",",
|
||||
"M": "."
|
||||
};
|
||||
const KEYBOARD_REV = {};
|
||||
for (const i of Object.keys(KEYBOARD)) {
|
||||
|
@ -156,7 +173,7 @@ export class Rotor extends Enigma.Rotor {
|
|||
let wiringMod = wiring;
|
||||
if (reversed) {
|
||||
const outMap = new Array(26);
|
||||
for (let i=0; i<26; i++) {
|
||||
for (let i = 0; i < 26; i++) {
|
||||
// wiring[i] is the original output
|
||||
// Enigma.LETTERS[i] is the original input
|
||||
const input = Utils.mod(26 - Enigma.a2i(wiring[i]), 26);
|
||||
|
@ -195,7 +212,7 @@ export class Plugboard extends Enigma.Rotor {
|
|||
throw new OperationError("Plugboard wiring must be 26 unique uppercase letters");
|
||||
}
|
||||
const reversed = "AZYXWVUTSRQPONMLKJIHGFEDCB";
|
||||
wiring = wiring.replace(/./g, x => {
|
||||
wiring = wiring.replace(/./g, (x) => {
|
||||
return reversed[Enigma.a2i(x)];
|
||||
});
|
||||
try {
|
||||
|
|
|
@ -13,7 +13,7 @@ const Zlib = zlibAndGzip.Zlib;
|
|||
export const COMPRESSION_TYPE = ["Dynamic Huffman Coding", "Fixed Huffman Coding", "None (Store)"];
|
||||
export const INFLATE_BUFFER_TYPE = ["Adaptive", "Block"];
|
||||
export const ZLIB_COMPRESSION_TYPE_LOOKUP = {
|
||||
"Fixed Huffman Coding": Zlib.Deflate.CompressionType.FIXED,
|
||||
"Fixed Huffman Coding": Zlib.Deflate.CompressionType.FIXED,
|
||||
"Dynamic Huffman Coding": Zlib.Deflate.CompressionType.DYNAMIC,
|
||||
"None (Store)": Zlib.Deflate.CompressionType.NONE,
|
||||
"None (Store)": Zlib.Deflate.CompressionType.NONE
|
||||
};
|
||||
|
|
|
@ -6,14 +6,13 @@
|
|||
|
||||
import Operation from "../Operation.mjs";
|
||||
import Utils from "../Utils.mjs";
|
||||
import {DELIM_OPTIONS} from "../lib/Delim.mjs";
|
||||
import { DELIM_OPTIONS } from "../lib/Delim.mjs";
|
||||
import OperationError from "../errors/OperationError.mjs";
|
||||
|
||||
/**
|
||||
* A1Z26 Cipher Decode operation
|
||||
*/
|
||||
class A1Z26CipherDecode extends Operation {
|
||||
|
||||
/**
|
||||
* A1Z26CipherDecode constructor
|
||||
*/
|
||||
|
@ -22,7 +21,8 @@ class A1Z26CipherDecode extends Operation {
|
|||
|
||||
this.name = "A1Z26 Cipher Decode";
|
||||
this.module = "Ciphers";
|
||||
this.description = "Converts alphabet order numbers into their corresponding alphabet character.<br><br>e.g. <code>1</code> becomes <code>a</code> and <code>2</code> becomes <code>b</code>.";
|
||||
this.description
|
||||
= "Converts alphabet order numbers into their corresponding alphabet character.<br><br>e.g. <code>1</code> becomes <code>a</code> and <code>2</code> becomes <code>b</code>.";
|
||||
this.infoURL = "";
|
||||
this.inputType = "string";
|
||||
this.outputType = "string";
|
||||
|
@ -35,34 +35,34 @@ class A1Z26CipherDecode extends Operation {
|
|||
];
|
||||
this.checks = [
|
||||
{
|
||||
pattern: "^\\s*([12]?[0-9] )+[12]?[0-9]\\s*$",
|
||||
flags: "",
|
||||
args: ["Space"]
|
||||
pattern: "^\\s*([12]?[0-9] )+[12]?[0-9]\\s*$",
|
||||
flags: "",
|
||||
args: ["Space"]
|
||||
},
|
||||
{
|
||||
pattern: "^\\s*([12]?[0-9],)+[12]?[0-9]\\s*$",
|
||||
flags: "",
|
||||
args: ["Comma"]
|
||||
pattern: "^\\s*([12]?[0-9],)+[12]?[0-9]\\s*$",
|
||||
flags: "",
|
||||
args: ["Comma"]
|
||||
},
|
||||
{
|
||||
pattern: "^\\s*([12]?[0-9];)+[12]?[0-9]\\s*$",
|
||||
flags: "",
|
||||
args: ["Semi-colon"]
|
||||
pattern: "^\\s*([12]?[0-9];)+[12]?[0-9]\\s*$",
|
||||
flags: "",
|
||||
args: ["Semi-colon"]
|
||||
},
|
||||
{
|
||||
pattern: "^\\s*([12]?[0-9]:)+[12]?[0-9]\\s*$",
|
||||
flags: "",
|
||||
args: ["Colon"]
|
||||
pattern: "^\\s*([12]?[0-9]:)+[12]?[0-9]\\s*$",
|
||||
flags: "",
|
||||
args: ["Colon"]
|
||||
},
|
||||
{
|
||||
pattern: "^\\s*([12]?[0-9]\\n)+[12]?[0-9]\\s*$",
|
||||
flags: "",
|
||||
args: ["Line feed"]
|
||||
pattern: "^\\s*([12]?[0-9]\\n)+[12]?[0-9]\\s*$",
|
||||
flags: "",
|
||||
args: ["Line feed"]
|
||||
},
|
||||
{
|
||||
pattern: "^\\s*([12]?[0-9]\\r\\n)+[12]?[0-9]\\s*$",
|
||||
flags: "",
|
||||
args: ["CRLF"]
|
||||
pattern: "^\\s*([12]?[0-9]\\r\\n)+[12]?[0-9]\\s*$",
|
||||
flags: "",
|
||||
args: ["CRLF"]
|
||||
}
|
||||
];
|
||||
}
|
||||
|
@ -89,7 +89,6 @@ class A1Z26CipherDecode extends Operation {
|
|||
}
|
||||
return latin1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default A1Z26CipherDecode;
|
||||
|
|
|
@ -6,13 +6,12 @@
|
|||
|
||||
import Operation from "../Operation.mjs";
|
||||
import Utils from "../Utils.mjs";
|
||||
import {DELIM_OPTIONS} from "../lib/Delim.mjs";
|
||||
import { DELIM_OPTIONS } from "../lib/Delim.mjs";
|
||||
|
||||
/**
|
||||
* A1Z26 Cipher Encode operation
|
||||
*/
|
||||
class A1Z26CipherEncode extends Operation {
|
||||
|
||||
/**
|
||||
* A1Z26CipherEncode constructor
|
||||
*/
|
||||
|
@ -21,7 +20,8 @@ class A1Z26CipherEncode extends Operation {
|
|||
|
||||
this.name = "A1Z26 Cipher Encode";
|
||||
this.module = "Ciphers";
|
||||
this.description = "Converts alphabet characters into their corresponding alphabet order number.<br><br>e.g. <code>a</code> becomes <code>1</code> and <code>b</code> becomes <code>2</code>.<br><br>Non-alphabet characters are dropped.";
|
||||
this.description
|
||||
= "Converts alphabet characters into their corresponding alphabet order number.<br><br>e.g. <code>a</code> becomes <code>1</code> and <code>b</code> becomes <code>2</code>.<br><br>Non-alphabet characters are dropped.";
|
||||
this.infoURL = "";
|
||||
this.inputType = "string";
|
||||
this.outputType = "string";
|
||||
|
@ -55,7 +55,6 @@ class A1Z26CipherEncode extends Operation {
|
|||
}
|
||||
return output.slice(0, -delim.length);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default A1Z26CipherEncode;
|
||||
|
|
|
@ -12,7 +12,6 @@ import { bitOp, add, BITWISE_OP_DELIMS } from "../lib/BitwiseOp.mjs";
|
|||
* ADD operation
|
||||
*/
|
||||
class ADD extends Operation {
|
||||
|
||||
/**
|
||||
* ADD constructor
|
||||
*/
|
||||
|
@ -71,7 +70,6 @@ class ADD extends Operation {
|
|||
highlightReverse(pos, args) {
|
||||
return pos;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default ADD;
|
||||
|
|
|
@ -13,7 +13,6 @@ import OperationError from "../errors/OperationError.mjs";
|
|||
* AES Decrypt operation
|
||||
*/
|
||||
class AESDecrypt extends Operation {
|
||||
|
||||
/**
|
||||
* AESDecrypt constructor
|
||||
*/
|
||||
|
@ -22,7 +21,8 @@ class AESDecrypt extends Operation {
|
|||
|
||||
this.name = "AES Decrypt";
|
||||
this.module = "Ciphers";
|
||||
this.description = "Advanced Encryption Standard (AES) is a U.S. Federal Information Processing Standard (FIPS). It was selected after a 5-year process where 15 competing designs were evaluated.<br><br><b>Key:</b> The following algorithms will be used based on the size of the key:<ul><li>16 bytes = AES-128</li><li>24 bytes = AES-192</li><li>32 bytes = AES-256</li></ul><br><br><b>IV:</b> The Initialization Vector should be 16 bytes long. If not entered, it will default to 16 null bytes.<br><br><b>Padding:</b> In CBC and ECB mode, PKCS#7 padding will be used as a default.<br><br><b>GCM Tag:</b> This field is ignored unless 'GCM' mode is used.";
|
||||
this.description
|
||||
= "Advanced Encryption Standard (AES) is a U.S. Federal Information Processing Standard (FIPS). It was selected after a 5-year process where 15 competing designs were evaluated.<br><br><b>Key:</b> The following algorithms will be used based on the size of the key:<ul><li>16 bytes = AES-128</li><li>24 bytes = AES-192</li><li>32 bytes = AES-256</li></ul><br><br><b>IV:</b> The Initialization Vector should be 16 bytes long. If not entered, it will default to 16 null bytes.<br><br><b>Padding:</b> In CBC and ECB mode, PKCS#7 padding will be used as a default.<br><br><b>GCM Tag:</b> This field is ignored unless 'GCM' mode is used.";
|
||||
this.infoURL = "https://wikipedia.org/wiki/Advanced_Encryption_Standard";
|
||||
this.inputType = "string";
|
||||
this.outputType = "string";
|
||||
|
@ -134,7 +134,7 @@ The following algorithms will be used based on the size of the key:
|
|||
|
||||
/* Allow for a "no padding" mode */
|
||||
if (noPadding) {
|
||||
decipher.mode.unpad = function(output, options) {
|
||||
decipher.mode.unpad = function (output, options) {
|
||||
return true;
|
||||
};
|
||||
}
|
||||
|
@ -153,7 +153,6 @@ The following algorithms will be used based on the size of the key:
|
|||
throw new OperationError("Unable to decrypt input with these parameters.");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default AESDecrypt;
|
||||
|
|
|
@ -13,7 +13,6 @@ import OperationError from "../errors/OperationError.mjs";
|
|||
* AES Encrypt operation
|
||||
*/
|
||||
class AESEncrypt extends Operation {
|
||||
|
||||
/**
|
||||
* AESEncrypt constructor
|
||||
*/
|
||||
|
@ -22,7 +21,8 @@ class AESEncrypt extends Operation {
|
|||
|
||||
this.name = "AES Encrypt";
|
||||
this.module = "Ciphers";
|
||||
this.description = "Advanced Encryption Standard (AES) is a U.S. Federal Information Processing Standard (FIPS). It was selected after a 5-year process where 15 competing designs were evaluated.<br><br><b>Key:</b> The following algorithms will be used based on the size of the key:<ul><li>16 bytes = AES-128</li><li>24 bytes = AES-192</li><li>32 bytes = AES-256</li></ul>You can generate a password-based key using one of the KDF operations.<br><br><b>IV:</b> The Initialization Vector should be 16 bytes long. If not entered, it will default to 16 null bytes.<br><br><b>Padding:</b> In CBC and ECB mode, PKCS#7 padding will be used.";
|
||||
this.description
|
||||
= "Advanced Encryption Standard (AES) is a U.S. Federal Information Processing Standard (FIPS). It was selected after a 5-year process where 15 competing designs were evaluated.<br><br><b>Key:</b> The following algorithms will be used based on the size of the key:<ul><li>16 bytes = AES-128</li><li>24 bytes = AES-192</li><li>32 bytes = AES-256</li></ul>You can generate a password-based key using one of the KDF operations.<br><br><b>IV:</b> The Initialization Vector should be 16 bytes long. If not entered, it will default to 16 null bytes.<br><br><b>Padding:</b> In CBC and ECB mode, PKCS#7 padding will be used.";
|
||||
this.infoURL = "https://wikipedia.org/wiki/Advanced_Encryption_Standard";
|
||||
this.inputType = "string";
|
||||
this.outputType = "string";
|
||||
|
@ -124,19 +124,16 @@ The following algorithms will be used based on the size of the key:
|
|||
|
||||
if (outputType === "Hex") {
|
||||
if (mode === "GCM") {
|
||||
return cipher.output.toHex() + "\n\n" +
|
||||
"Tag: " + cipher.mode.tag.toHex();
|
||||
return cipher.output.toHex() + "\n\n" + "Tag: " + cipher.mode.tag.toHex();
|
||||
}
|
||||
return cipher.output.toHex();
|
||||
} else {
|
||||
if (mode === "GCM") {
|
||||
return cipher.output.getBytes() + "\n\n" +
|
||||
"Tag: " + cipher.mode.tag.getBytes();
|
||||
return cipher.output.getBytes() + "\n\n" + "Tag: " + cipher.mode.tag.getBytes();
|
||||
}
|
||||
return cipher.output.getBytes();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default AESEncrypt;
|
||||
|
|
|
@ -14,7 +14,6 @@ import OperationError from "../errors/OperationError.mjs";
|
|||
* AES Key Unwrap operation
|
||||
*/
|
||||
class AESKeyUnwrap extends Operation {
|
||||
|
||||
/**
|
||||
* AESKeyUnwrap constructor
|
||||
*/
|
||||
|
@ -23,7 +22,8 @@ class AESKeyUnwrap extends Operation {
|
|||
|
||||
this.name = "AES Key Unwrap";
|
||||
this.module = "Ciphers";
|
||||
this.description = "Decryptor for a key wrapping algorithm defined in RFC3394, which is used to protect keys in untrusted storage or communications, using AES.<br><br>This algorithm uses an AES key (KEK: key-encryption key) and a 64-bit IV to decrypt 64-bit blocks.";
|
||||
this.description
|
||||
= "Decryptor for a key wrapping algorithm defined in RFC3394, which is used to protect keys in untrusted storage or communications, using AES.<br><br>This algorithm uses an AES key (KEK: key-encryption key) and a 64-bit IV to decrypt 64-bit blocks.";
|
||||
this.infoURL = "https://wikipedia.org/wiki/Key_wrap";
|
||||
this.inputType = "string";
|
||||
this.outputType = "string";
|
||||
|
@ -49,7 +49,7 @@ class AESKeyUnwrap extends Operation {
|
|||
"name": "Output",
|
||||
"type": "option",
|
||||
"value": ["Hex", "Raw"]
|
||||
},
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
|
@ -90,8 +90,8 @@ class AESKeyUnwrap extends Operation {
|
|||
}
|
||||
let cntLower = R.length >>> 0;
|
||||
let cntUpper = (R.length / ((1 << 30) * 4)) >>> 0;
|
||||
cntUpper = cntUpper * 6 + ((cntLower * 6 / ((1 << 30) * 4)) >>> 0);
|
||||
cntLower = cntLower * 6 >>> 0;
|
||||
cntUpper = cntUpper * 6 + (((cntLower * 6) / ((1 << 30) * 4)) >>> 0);
|
||||
cntLower = (cntLower * 6) >>> 0;
|
||||
for (let j = 5; j >= 0; j--) {
|
||||
for (let i = R.length - 1; i >= 0; i--) {
|
||||
const aBuffer = Utils.strToArrayBuffer(A);
|
||||
|
@ -122,7 +122,6 @@ class AESKeyUnwrap extends Operation {
|
|||
}
|
||||
return P;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default AESKeyUnwrap;
|
||||
|
|
|
@ -14,7 +14,6 @@ import OperationError from "../errors/OperationError.mjs";
|
|||
* AES Key Wrap operation
|
||||
*/
|
||||
class AESKeyWrap extends Operation {
|
||||
|
||||
/**
|
||||
* AESKeyWrap constructor
|
||||
*/
|
||||
|
@ -23,7 +22,8 @@ class AESKeyWrap extends Operation {
|
|||
|
||||
this.name = "AES Key Wrap";
|
||||
this.module = "Ciphers";
|
||||
this.description = "A key wrapping algorithm defined in RFC3394, which is used to protect keys in untrusted storage or communications, using AES.<br><br>This algorithm uses an AES key (KEK: key-encryption key) and a 64-bit IV to encrypt 64-bit blocks.";
|
||||
this.description
|
||||
= "A key wrapping algorithm defined in RFC3394, which is used to protect keys in untrusted storage or communications, using AES.<br><br>This algorithm uses an AES key (KEK: key-encryption key) and a 64-bit IV to encrypt 64-bit blocks.";
|
||||
this.infoURL = "https://wikipedia.org/wiki/Key_wrap";
|
||||
this.inputType = "string";
|
||||
this.outputType = "string";
|
||||
|
@ -49,7 +49,7 @@ class AESKeyWrap extends Operation {
|
|||
"name": "Output",
|
||||
"type": "option",
|
||||
"value": ["Hex", "Raw"]
|
||||
},
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
|
@ -82,7 +82,8 @@ class AESKeyWrap extends Operation {
|
|||
for (let i = 0; i < inputData.length; i += 8) {
|
||||
R.push(inputData.substring(i, i + 8));
|
||||
}
|
||||
let cntLower = 1, cntUpper = 0;
|
||||
let cntLower = 1,
|
||||
cntUpper = 0;
|
||||
for (let j = 0; j < 6; j++) {
|
||||
for (let i = 0; i < R.length; i++) {
|
||||
cipher.start();
|
||||
|
@ -109,7 +110,6 @@ class AESKeyWrap extends Operation {
|
|||
}
|
||||
return C;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default AESKeyWrap;
|
||||
|
|
|
@ -12,7 +12,6 @@ import { AMF0, AMF3 } from "@astronautlabs/amf";
|
|||
* AMF Decode operation
|
||||
*/
|
||||
class AMFDecode extends Operation {
|
||||
|
||||
/**
|
||||
* AMFDecode constructor
|
||||
*/
|
||||
|
@ -21,7 +20,8 @@ class AMFDecode extends Operation {
|
|||
|
||||
this.name = "AMF Decode";
|
||||
this.module = "Encodings";
|
||||
this.description = "Action Message Format (AMF) is a binary format used to serialize object graphs such as ActionScript objects and XML, or send messages between an Adobe Flash client and a remote service, usually a Flash Media Server or third party alternatives.";
|
||||
this.description
|
||||
= "Action Message Format (AMF) is a binary format used to serialize object graphs such as ActionScript objects and XML, or send messages between an Adobe Flash client and a remote service, usually a Flash Media Server or third party alternatives.";
|
||||
this.infoURL = "https://wikipedia.org/wiki/Action_Message_Format";
|
||||
this.inputType = "ArrayBuffer";
|
||||
this.outputType = "JSON";
|
||||
|
@ -46,7 +46,6 @@ class AMFDecode extends Operation {
|
|||
const encoded = new Uint8Array(input);
|
||||
return handler.Value.deserialize(encoded);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default AMFDecode;
|
||||
|
|
|
@ -12,7 +12,6 @@ import { AMF0, AMF3 } from "@astronautlabs/amf";
|
|||
* AMF Encode operation
|
||||
*/
|
||||
class AMFEncode extends Operation {
|
||||
|
||||
/**
|
||||
* AMFEncode constructor
|
||||
*/
|
||||
|
@ -21,7 +20,8 @@ class AMFEncode extends Operation {
|
|||
|
||||
this.name = "AMF Encode";
|
||||
this.module = "Encodings";
|
||||
this.description = "Action Message Format (AMF) is a binary format used to serialize object graphs such as ActionScript objects and XML, or send messages between an Adobe Flash client and a remote service, usually a Flash Media Server or third party alternatives.";
|
||||
this.description
|
||||
= "Action Message Format (AMF) is a binary format used to serialize object graphs such as ActionScript objects and XML, or send messages between an Adobe Flash client and a remote service, usually a Flash Media Server or third party alternatives.";
|
||||
this.infoURL = "https://wikipedia.org/wiki/Action_Message_Format";
|
||||
this.inputType = "JSON";
|
||||
this.outputType = "ArrayBuffer";
|
||||
|
@ -46,7 +46,6 @@ class AMFEncode extends Operation {
|
|||
const output = handler.Value.any(input).serialize();
|
||||
return output.buffer;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default AMFEncode;
|
||||
|
|
|
@ -12,7 +12,6 @@ import { bitOp, and, BITWISE_OP_DELIMS } from "../lib/BitwiseOp.mjs";
|
|||
* AND operation
|
||||
*/
|
||||
class AND extends Operation {
|
||||
|
||||
/**
|
||||
* AND constructor
|
||||
*/
|
||||
|
@ -71,7 +70,6 @@ class AND extends Operation {
|
|||
highlightReverse(pos, args) {
|
||||
return pos;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default AND;
|
||||
|
|
|
@ -10,7 +10,6 @@ import Operation from "../Operation.mjs";
|
|||
* Add line numbers operation
|
||||
*/
|
||||
class AddLineNumbers extends Operation {
|
||||
|
||||
/**
|
||||
* AddLineNumbers constructor
|
||||
*/
|
||||
|
@ -36,11 +35,10 @@ class AddLineNumbers extends Operation {
|
|||
let output = "";
|
||||
|
||||
for (let n = 0; n < lines.length; n++) {
|
||||
output += (n+1).toString().padStart(width, " ") + " " + lines[n] + "\n";
|
||||
output += (n + 1).toString().padStart(width, " ") + " " + lines[n] + "\n";
|
||||
}
|
||||
return output.slice(0, output.length-1);
|
||||
return output.slice(0, output.length - 1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default AddLineNumbers;
|
||||
|
|
|
@ -15,7 +15,6 @@ import jimp from "jimp";
|
|||
* Add Text To Image operation
|
||||
*/
|
||||
class AddTextToImage extends Operation {
|
||||
|
||||
/**
|
||||
* AddTextToImage constructor
|
||||
*/
|
||||
|
@ -24,7 +23,8 @@ class AddTextToImage extends Operation {
|
|||
|
||||
this.name = "Add Text To Image";
|
||||
this.module = "Image";
|
||||
this.description = "Adds text onto an image.<br><br>Text can be horizontally or vertically aligned, or the position can be manually specified.<br>Variants of the Roboto font face are available in any size or colour.";
|
||||
this.description
|
||||
= "Adds text onto an image.<br><br>Text can be horizontally or vertically aligned, or the position can be manually specified.<br>Variants of the Roboto font face are available in any size or colour.";
|
||||
this.infoURL = "";
|
||||
this.inputType = "ArrayBuffer";
|
||||
this.outputType = "ArrayBuffer";
|
||||
|
@ -64,12 +64,7 @@ class AddTextToImage extends Operation {
|
|||
{
|
||||
name: "Font face",
|
||||
type: "option",
|
||||
value: [
|
||||
"Roboto",
|
||||
"Roboto Black",
|
||||
"Roboto Mono",
|
||||
"Roboto Slab"
|
||||
]
|
||||
value: ["Roboto", "Roboto Black", "Roboto Mono", "Roboto Slab"]
|
||||
},
|
||||
{
|
||||
name: "Red",
|
||||
|
@ -132,8 +127,7 @@ class AddTextToImage extends Operation {
|
|||
throw new OperationError(`Error loading image. (${err})`);
|
||||
}
|
||||
try {
|
||||
if (isWorkerEnvironment())
|
||||
self.sendStatusMessage("Adding text to image...");
|
||||
if (isWorkerEnvironment()) self.sendStatusMessage("Adding text to image...");
|
||||
|
||||
const fontsMap = {};
|
||||
const fonts = [
|
||||
|
@ -143,14 +137,12 @@ class AddTextToImage extends Operation {
|
|||
import(/* webpackMode: "eager" */ "../../web/static/fonts/bmfonts/RobotoSlab72White.fnt")
|
||||
];
|
||||
|
||||
await Promise.all(fonts)
|
||||
.then(fonts => {
|
||||
fontsMap.Roboto = fonts[0];
|
||||
fontsMap["Roboto Black"] = fonts[1];
|
||||
fontsMap["Roboto Mono"] = fonts[2];
|
||||
fontsMap["Roboto Slab"] = fonts[3];
|
||||
});
|
||||
|
||||
await Promise.all(fonts).then((fonts) => {
|
||||
fontsMap.Roboto = fonts[0];
|
||||
fontsMap["Roboto Black"] = fonts[1];
|
||||
fontsMap["Roboto Mono"] = fonts[2];
|
||||
fontsMap["Roboto Slab"] = fonts[3];
|
||||
});
|
||||
|
||||
// Make Webpack load the png font images
|
||||
await Promise.all([
|
||||
|
@ -165,7 +157,7 @@ class AddTextToImage extends Operation {
|
|||
// LoadFont needs an absolute url, so append the font name to self.docURL
|
||||
const jimpFont = await jimp.loadFont(self.docURL + "/" + font.default);
|
||||
|
||||
jimpFont.pages.forEach(function(page) {
|
||||
jimpFont.pages.forEach(function (page) {
|
||||
if (page.bitmap) {
|
||||
// Adjust the RGB values of the image pages to change the font colour.
|
||||
const pageWidth = page.bitmap.width;
|
||||
|
@ -180,10 +172,10 @@ class AddTextToImage extends Operation {
|
|||
const newAlpha = page.bitmap.data[idx + 3] - (255 - alpha);
|
||||
|
||||
// Make sure the bitmap values don't go below 0 as that makes jimp very unhappy
|
||||
page.bitmap.data[idx] = (newRed > 0) ? newRed : 0;
|
||||
page.bitmap.data[idx + 1] = (newGreen > 0) ? newGreen : 0;
|
||||
page.bitmap.data[idx + 2] = (newBlue > 0) ? newBlue : 0;
|
||||
page.bitmap.data[idx + 3] = (newAlpha > 0) ? newAlpha : 0;
|
||||
page.bitmap.data[idx] = newRed > 0 ? newRed : 0;
|
||||
page.bitmap.data[idx + 1] = newGreen > 0 ? newGreen : 0;
|
||||
page.bitmap.data[idx + 2] = newBlue > 0 ? newBlue : 0;
|
||||
page.bitmap.data[idx + 3] = newAlpha > 0 ? newAlpha : 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -210,7 +202,7 @@ class AddTextToImage extends Operation {
|
|||
xPos = 0;
|
||||
break;
|
||||
case "Center":
|
||||
xPos = (image.getWidth() / 2) - (textImage.getWidth() / 2);
|
||||
xPos = image.getWidth() / 2 - textImage.getWidth() / 2;
|
||||
break;
|
||||
case "Right":
|
||||
xPos = image.getWidth() - textImage.getWidth();
|
||||
|
@ -222,7 +214,7 @@ class AddTextToImage extends Operation {
|
|||
yPos = 0;
|
||||
break;
|
||||
case "Middle":
|
||||
yPos = (image.getHeight() / 2) - (textImage.getHeight() / 2);
|
||||
yPos = image.getHeight() / 2 - textImage.getHeight() / 2;
|
||||
break;
|
||||
case "Bottom":
|
||||
yPos = image.getHeight() - textImage.getHeight();
|
||||
|
@ -261,7 +253,6 @@ class AddTextToImage extends Operation {
|
|||
|
||||
return `<img src="data:${type};base64,${toBase64(dataArray)}">`;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default AddTextToImage;
|
||||
|
|
|
@ -11,7 +11,6 @@ import Utils from "../Utils.mjs";
|
|||
* Adler-32 Checksum operation
|
||||
*/
|
||||
class Adler32Checksum extends Operation {
|
||||
|
||||
/**
|
||||
* Adler32Checksum constructor
|
||||
*/
|
||||
|
@ -20,7 +19,8 @@ class Adler32Checksum extends Operation {
|
|||
|
||||
this.name = "Adler-32 Checksum";
|
||||
this.module = "Crypto";
|
||||
this.description = "Adler-32 is a checksum algorithm which was invented by Mark Adler in 1995, and is a modification of the Fletcher checksum. Compared to a cyclic redundancy check of the same length, it trades reliability for speed (preferring the latter).<br><br>Adler-32 is more reliable than Fletcher-16, and slightly less reliable than Fletcher-32.";
|
||||
this.description
|
||||
= "Adler-32 is a checksum algorithm which was invented by Mark Adler in 1995, and is a modification of the Fletcher checksum. Compared to a cyclic redundancy check of the same length, it trades reliability for speed (preferring the latter).<br><br>Adler-32 is more reliable than Fletcher-16, and slightly less reliable than Fletcher-32.";
|
||||
this.infoURL = "https://wikipedia.org/wiki/Adler-32";
|
||||
this.inputType = "ArrayBuffer";
|
||||
this.outputType = "string";
|
||||
|
@ -48,7 +48,6 @@ class Adler32Checksum extends Operation {
|
|||
|
||||
return Utils.hex(((b << 16) | a) >>> 0, 8);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default Adler32Checksum;
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue