AnyankaKeys/Public/ecma/AnyankaKeys.ecma.js

1032 lines
36 KiB
JavaScript

/**
* @author KyMAN
* @version 20241105
*/
/**
* @callback anyanka_keys_default_callback
* @returns {void}
*/
/**
* @callback anyanka_keys_convert_callback
* @param {!number} value
* @returns {void}
*/
/**
* @callback anyanka_keys_data_callback
* @param {!string} data
* @param {!number} length
* @returns {void}
*/
/**
* @callback anyanka_keys_value_callback
* @param {!number} value
* @param {!number} i
* @returns {void}
*/
/**
* @class
* @constructor
* @param {Object.<string, any|null>} [inputs = {}]
* @returns {void}
* @access public
*/
export const AnyankaKeys = (function(){
/**
* @constructs AnyankaKeys
* @param {Object.<string, any|null>} [inputs = {}]
* @returns {void}
* @access private
*/
const AnyankaKeys = function(inputs = {}){
/** @type {AnyankaKeys} */
const self = this,
/** @type {Array.<number>} */
public_key = [],
/** @type {Array.<number>} */
private_key = [],
/** @type {AnyankaKeys.Options} */
options = new AnyankaKeys.Options(inputs);
/** @type {string} */
let alphabet = AnyankaKeys.SETTINGS.alpahbet,
/** @type {number} */
base_from = AnyankaKeys.SETTINGS.base_from,
/** @type {number} */
base_to = AnyankaKeys.SETTINGS.base_to,
/** @type {number} */
divisor = AnyankaKeys.SETTINGS.divisor,
/** @type {number} */
public_key_length = AnyankaKeys.SETTINGS.public_key_length,
/** @type {number} */
private_key_length = AnyankaKeys.SETTINGS.private_key_length,
/** @type {number} */
segments_key_length = AnyankaKeys.SETTINGS.segments_key_length,
/** @type {number|boolean|null} */
summatory_value = AnyankaKeys.SETTINGS.summatory,
/** @type {boolean} */
has_incremental = AnyankaKeys.SETTINGS.incremental,
/** @type {boolean|number|null} */
random_private_start = AnyankaKeys.SETTINGS.random_private_start,
/** @type {number} */
hash_length = AnyankaKeys.SETTINGS.hash_length,
/** @type {number} */
hash_power = AnyankaKeys.SETTINGS.hash_power;
/**
* @returns {void}
* @access private
*/
const constructor = () => {
if(inputs){
if(typeof inputs == "string")
inputs = {alphabet : inputs};
else if(!AnyankaKeys.is_dictionary(inputs))
inputs = {};
}else
inputs = {};
inputs.alphabet !== undefined && (alphabet = inputs.alphabet);
inputs.base_from !== undefined && (base_from = inputs.base_from);
inputs.base_to !== undefined && (base_to = inputs.base_to);
inputs.public_key_length !== undefined && (public_key_length = inputs.public_key_length);
inputs.private_key_length !== undefined && (private_key_length = inputs.private_key_length);
inputs.segments_key_length !== undefined && (segments_key_length = inputs.segments_key_length);
inputs.summatory !== undefined && (summatory_value = inputs.summatory);
inputs.incremental !== undefined && (has_incremental = inputs.incremental);
inputs.random_private_start !== undefined && (random_private_start = inputs.random_private_start);
inputs.hash_length !== undefined && (hash_length = inputs.hash_length);
inputs.hash_power !== undefined && (hash_power = inputs.hash_power);
(
typeof (alphabet = inputs.alphabet) != "string" ||
(alphabet = [...alphabet].filter((character, index) => alphabet.indexOf(character) == index)).length < 1
) && (alphabet = AnyankaKeys.SETTINGS.alphabet);
(
typeof (base_from = inputs.base_from) != "number" ||
base_from != base_from >> 0 ||
base_from < 2
) && (base_from = AnyankaKeys.SETTINGS.base_from);
(
typeof (base_to = inputs.base_to) != "number" ||
base_to != base_to >> 0 ||
base_to < 2 ||
base_to >= alphabet.length
) && (base_to = AnyankaKeys.SETTINGS.base_to);
self.set_public_key(true);
typeof summatory_value != "number" && summatory_value !== true && summatory_value !== null && (summatory_value = AnyankaKeys.SETTINGS.summatory);
typeof has_incremental != "boolean" && (has_incremental = AnyankaKeys.SETTINGS.incremental);
typeof random_private_start != "number" && random_private_start !== true && random_private_start !== null && (random_private_start = AnyankaKeys.SETTINGS.random_private_start);
typeof hash_length != "number" && (hash_length = AnyankaKeys.SETTINGS.hash_length);
typeof hash_power != "number" && (hash_power = AnyankaKeys.SETTINGS.hash_power);
};
/**
* @returns {string|null}
* @access public
*/
this.get_public_key = () => public_key.length ? public_key.map(key => alphabet[key]).join("") : null;
/**
* @param {!number} x
* @returns {number}
* @access private
*/
const next = x => {
x += 1 + divisor;
while(x >= 2)
x --;
return x;
};
/**
* @param {string|boolean|null} [new_key = null]
* @returns {number}
* @access public
*/
this.set_public_key = (new_key = null) => {
/** @type {number} */
let error = 0;
if(new_key === undefined)
error |= 1 << 1;
else{
if(new_key === null){
AnyankaKeys.reset_array_with(public_key);
AnyankaKeys.reset_array_with(private_key, [0]);
}else{
/** @type {Array.<number>|null} */
let new_public_key = null;
switch(typeof new_key){
case "boolean":
if(new_key)
new_public_key = Array.from({
length : public_key_length
}, () => Math.random() * base_to >> 0);
else
error |= 1 << 4;
break;
case "string":
new_public_key = [...new_key].map(character => alphabet.indexOf(character));
if(Math.min(new_public_key) == -1)
error |= 1 << 5;
break;
default:
error |= 1 << 3;
break;
};
if(!error){
AnyankaKeys.reset_array_with(public_key, new_public_key);
/** @type {number} */
const segment = public_key.length / segments_key_length >> 0,
/** @type {number} */
start = Number(("" + divisor).split(".")[1]) % base_to;
/** @type {number} */
let x = 1;
public_key.length && AnyankaKeys.reset_array_with(private_key, Array.from({
length : private_key_length
}, (_, i) => (AnyankaKeys.summatory(
segments_key_length,
j => public_key[(j * segment + i) % public_key_length],
start,
base_to
) * (x = next(x)) >> 0) % base_to));
};
};
};
return error;
};
/**
* @param {!number} i
* @param {!number} value
* @returns {string}
* @access private
*/
const set_key = (i, value) => alphabet[(value + private_key[i % private_key_length]) % base_to];
/**
* @param {!(any|null)} data
* @returns {string}
* @access public
*/
this.encrypt = data => {
/** @type {string} */
let header = "",
/** @type {string} */
body = "",
/** @type {number} */
pre_empties = 0,
/** @type {number} */
i = 0;
/** @type {AnyankaKeys.BaseChange.Parameters} */
const parameters = new AnyankaKeys.BaseChange.Parameters({
/** @type {number} */
from : base_from,
/** @type {number} */
to : base_to
}),
/** @type {Array.<number>} */
header_data = (
random_private_start === true ? Array.from({length : 2}, () => Math.random() * base_to >> 0) :
typeof random_private_start == "number" ? Array.from([base_to, 1], i => (random_private_start / i >> 0) % base_to) :
[0, 0]),
/** @type {number} */
summatory = (summatory_value === true ? Math.random() * base_to >> 0 : summatory_value % 58) || 1;
/** @type {number} */
private_start = (header_data[0] * base_to + header_data[1]) % private_key_length,
/** @type {anyanka_keys_convert_callback} */
set = value => body = set_key(private_start + (has_incremental ? i ++ : 1) * summatory, value) + body,
/** @type {AnyankaKeys.Type} */
type = AnyankaKeys.get_each_bytes(data, byte => AnyankaKeys.change_base_iteration(byte, set, parameters), options);
if([5, 6, 7, 8].includes(type.code))
data.some(value => {
if(value)
return true;
pre_empties ++;
});
else if(type.code == 10)
pre_empties = type.empties;
parameters.end(set);
header += alphabet[header_data[0]] + alphabet[header_data[1]] + set_key(private_start, summatory);
[type.code, pre_empties].forEach((value, i) => header += set_key(private_start + (has_incremental ? i : 1) * summatory, value));
return header + body;
};
/**
* @param {!number} i
* @param {!string} character
* @returns {number}
* @access private
*/
const get_key = (i, character) => {
/** @type {number} */
let value = alphabet.indexOf(character) - private_key[i % private_key_length];
return value < 0 ? value + base_to : value;
};
/**
* @param {!string} data
* @returns {any|null}
* @access public
*/
this.decrypt = data => {
/** @type {string} */
const header = data.substring(0, 5),
/** @type {AnyankaKeys.BaseChange.Parameters} */
parameters = new AnyankaKeys.BaseChange.Parameters({
/** @type {number} */
from : base_to,
/** @type {number} */
to : base_from
}),
/** @type {string} */
body = data.substring(5),
/** @type {number} */
body_l = body.length - 1,
/** @type {number} */
private_start = (alphabet.indexOf(header[0]) * base_to + alphabet.indexOf(header[1])) % private_key_length,
/** @type {number} */
summatory = get_key(private_start, header[2]),
/** @type {AnyankaKeys.Type} */
type = new AnyankaKeys.Type(get_key(
private_start + (has_incremental ? 0 : summatory), header[3]
), body, parameters.get_size(body), options);
/** @type {number} */
let pre_empties = get_key(private_start + summatory, header[4]);
[...body].forEach((character, i) => AnyankaKeys.change_base_iteration(get_key(
private_start + (has_incremental ? body_l - i : 1) * summatory, character
), type.set_value, parameters));
parameters.end(type.set_value);
(pre_empties == type.length() ? -- pre_empties : pre_empties) > 0 && type.set_pre_empties(pre_empties);
type.build();
return type.data;
};
/**
* @param {any|null} data
* @returns {string}
* @access public
*/
this.hash = data => {
/** @type {number} */
let summatory = 1,
/** @type {number} */
i = 0,
/** @type {number} */
x = 1,
/** @type {number} */
wise = 0;
/** @type {Array.<number>} */
const hash = Array.from({length : hash_length}, () => 0),
/** @type {number} */
value_limit = base_to ** hash_power,
/** @type {AnyankaKeys.Type} */
type = AnyankaKeys.get_each_bytes(data, byte => {
/** @type {number} */
const k = i ++ % hash_length;
summatory = (summatory + byte) % value_limit;
hash[k] = (hash[k] + byte) % value_limit;
}, new AnyankaKeys.Options()),
/** @type {number} */
base = summatory ** divisor / ++ i ** divisor;
hash[0] += type.code;
return hash.map(value => {
value = wise ** (x = next(x)) + (base * value) ** x + base ** x;
while((value *= base_to) < value_limit);
wise += (value = (value >> 0) % base_to);
return alphabet[value];
}).join("");
};
constructor();
};
/** @type {Object.<string, string|number|boolean|null>} */
AnyankaKeys.SETTINGS = {
/** @type {string} */
alphabet : "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz",
/** @type {number} */
base_to : 58, // Cast for unique alphabet characters.
/** @type {number} */
base_from : 256,
/** @type {boolean|string|null} */
public_key : true, // true = Random || null = No keys || String = Default key
/** @type {number} */
public_key_length : 1 << 8,
/** @type {number} */
private_key_length : 1 << 12,
/** @type {number} */
segments_key_length : 13,
/** @type {boolean|number|null} */
summatory : true, // true = Random || null = No summatory || number = Default summatory
/** @type {boolean} */
incremental : true,
/** @type {boolean|number|null} */
random_private_start : true,
/** @type {number} */
divisor : .21417,
/** @type {number} */
hash_length : 47,
/** @type {number} */
hash_power : 1.89673,
/** @type {number} */
scape_character : 92, // Character ["\\", 92]
/** @type {number} */
scape_blocks : 2 // Bits: [UTF-8, UTF-16, URI, Force UTF-16]
};
/**
* @param {!number} length
* @param {!anyanka_keys_convert_callback} item_callback
* @returns {void}
* @access public
* @static
*/
AnyankaKeys.bucle = (length, item_callback) => {
/** @type {number} */
let i = 0;
while(i < length)
item_callback(i ++);
};
/**
* @param {!number} length
* @param {!anyanka_keys_convert_callback} callback
* @param {!number} [start = 0]
* @param {?number} [limit = null]
* @returns {number}
* @access public
* @static
*/
AnyankaKeys.summatory = (length, callback, start = 0, limit = null) => {
limit || (limit = ~-(1 << 31));
AnyankaKeys.bucle(length, i => start = (start + callback(i)) % limit);
return start;
};
/**
* @param {!Array.<any|null>} array
* @param {Array.<any|null>} [new_data = []]
* @returns {void}
* @access public
* @static
*/
AnyankaKeys.reset_array_with = (array, new_data = []) => {
array.splice(0, array.length, ...new_data);
};
/**
* @constructor
* @param {!Object.<string, number>} [inputs = {}]
* @returns {void}
* @access public
* @static
*/
AnyankaKeys.Options = function(inputs = {}){
/** @type {number} */
this.scape_blocks = (
inputs.scape_blocks !== undefined &&
typeof inputs.scape_blocks == "number" &&
inputs.scape_blocks >= 0 &&
inputs.scape_blocks <= 4
) ? inputs.scape_blocks : AnyankaKeys.SETTINGS.scape_blocks;
/** @type {number} */
this.scape_character = (
inputs.scape_character !== undefined &&
typeof inputs.scape_character == "number" &&
inputs.scape_character & 0xFF == inputs.scape_character
) ? inputs.scape_character : AnyankaKeys.SETTINGS.scape_character;
/** @type {boolean} */
this.scape_utf8 = !!(this.scape_blocks & (1 << 0));
/** @type {boolean} */
this.scape_utf16 = !!(this.scape_blocks & (1 << 1));
/** @type {boolean} */
this.scape_uri = !!(this.scape_blocks & (1 << 2));
/** @type {boolean} */
this.force_utf16 = !!(this.scape_blocks & (1 << 3));
/** @type {boolean} */
this.scape = this.scape_utf8 || this.scape_utf16;
};
/**
* @constructor
* @param {string|number} [name = "unknown"]
* @param {string|null} [data = null]
* @param {number} [length = 0]
* @param {?AnyankaKeys.Options} [options = null]
* @returns {void}
* @access public
*/
AnyankaKeys.Type = function(name = "unknown", data = null, length = 0, options = null){
/** @type {AnyankaKeys.Type} */
const self = this;
/** @type {any|null} */
let cache = null,
/** @type {Array.<number>|null} */
string_cache = null;
/** @type {number} */
this.code = 0;
/** @type {string} */
this.name = name;
/** @type {any|null} */
this.data = null;
/** @type {number} */
this.empties = 0;
/**
* @returns {void}
* @access private
*/
const constructor = () => {
if(typeof name == "number")
self.name = AnyankaKeys.Type.TYPES[self.code = name];
else if(name){
if(self.code = AnyankaKeys.Type.TYPES.indexOf(name = name.toLowerCase()) != -1)
self.name = name;
else
self.code = 0;
};
data !== null && self.start(data, length);
options || (options = new AnyankaKeys.Options());
};
/**
* @param {!number} code
* @param {?name} [name = null]
* @returns {void}
* @access public
*/
this.set = (code, name = null) => {
self.code = code;
name && (self.name = name);
};
/**
* @param {!number} byte
* @returns {string}
* @access private
*/
const get_character_by_byte = (byte) => {
/** @type {string} */
let character = "",
/** @type {boolean} */
force_scape = false;
if(options.scape){
if(string_cache === null){
if(byte == options.scape_character)
string_cache = [];
else
character = String.fromCharCode(byte);
}else if(byte == options.scape_character){
if(!string_cache.length)
character = String.fromCharCode(byte);
else{
/** @type {number} */
let code = 0;
string_cache.forEach((byte, i) => code += byte << i * 8);
character = String.fromCharCode(code);
force_scape = true;
string_cache = [];
};
}else if(!string_cache.length){
if(options.scape_utf16)
string_cache.push(byte);
else
character = String.fromCharCode(string_cache[0]);
}else
character = String.fromCharCode(string_cache[0] | (byte << 8));
}else
character = String.fromCharCode(byte);
string_cache !== null && !force_scape && character !== "" && (string_cache = null);
return character;
};
/** @type {Object.<string, Object.<string, anyanka_keys_data_callback>|Object.<string, anyanka_keys_value_callback>|Object.<string, anyanka_keys_convert_callback>|Object.<string, anyanka_keys_default_callback>>} */
this.action = {
/** @type {Object.<string, anyanka_keys_data_callback>} */
start : {
unknown : (data, length) => {},
string : (data, length) => self.data = "",
undefined : (data, length) => self.data = undefined,
null : (data, length) => {},
json : (data, length) => cache = "",
utf8 : (data, length) => cache = [],
utf16 : (data, length) => cache = [],
utf32 : (data, length) => cache = [],
bytes : (data, length) => self.data = [],
bool : (data, length) => {},
integer : (data, length) => self.data = 0,
float : (data, length) => {},
custom : (data, length) => cache = []
},
/** @type {Object.<string, anyanka_keys_value_callback>} */
set_value : {
unknown : (value, i) => {},
string : (value, i) => self.data = get_character_by_byte(value) + self.data,
undefined : (value, i) => {},
null : (value, i) => {},
json : (value, i) => cache = get_character_by_byte(value) + cache,
utf8 : (value, i) => cache.unshift(value),
utf16 : (value, i) => {
if(i % 2)
cache[0] = (cache[0] << 8) | value;
else
cache.unshift(value);
},
utf32 : (value, i) => {
if(i % 4)
cache[0] = (cache[0] << 8) | value;
else
cache.unshift(value);
},
bytes : (value, i) => self.data.unshift(value),
bool : (value, i) => self.data = (
i ? null :
value === 1 ? true :
value === 0 ? false :
null),
integer : (value, i) => self.data = (self.data << 8) | value,
float : (value, i) => {},
custom : (value, i) => cache.push(value)
},
/** @type {Object.<string, anyanka_keys_convert_callback>} */
set_pre_empties : {
unknown : empties => {},
string : empties => {},
undefined : empties => {},
null : empties => {},
json : empties => {},
utf8 : empties => AnyankaKeys.bucle(empties, () => cache.unshift(0)),
utf16 : empties => AnyankaKeys.bucle(empties, () => cache.unshift(0)),
utf32 : empties => AnyankaKeys.bucle(empties, () => cache.unshift(0)),
bytes : empties => AnyankaKeys.bucle(empties, () => self.data.unshift(0)),
bool : empties => {},
integer : empties => self.data <<= empties * 8,
float : empties => {},
custom : empties => AnyankaKeys.bucle(empties, () => self.data.unshift(0))
},
/** @type {Object.<string, anyanka_keys_default_callback>} */
build : {
unknown : () => {},
string : () => {
string_cache !== null && (self.data = String.fromCharCode(0) + self.data);
options.scape_uri && (self.data = decodeURIComponent(self.data));
},
undefined : () => {},
null : () => {},
json : () => {
string_cache !== null && (cache = String.fromCharCode(0) + cache);
self.data = JSON.parse(cache ? options.scape_uri ? decodeURIComponent(cache) : cache : "[]");
},
utf8 : () => self.data = new Uint8Array(cache),
utf16 : () => self.data = new Uint16Array(cache),
utf32 : () => self.data = new Uint32Array(cache),
bytes : () => {},
bool : () => {},
integer : () => {},
float : () => {},
custom : () => {}
}
};
/**
* @param {!string} data
* @param {!number} length
* @returns {void}
* @access public
*/
this.start = (data, length) => {
self.action.start[self.name](data, length);
};
/**
* @param {!number} value
* @param {!number} i
* @returns {void}
* @access public
*/
this.set_value = (value, i) => {
self.action.set_value[self.name](value, i);
}
/**
* @param {!number} empties
* @returns {void}
* @access public
*/
this.set_pre_empties = empties => {
self.action.set_pre_empties[self.name](empties);
}
/**
* @returns {void}
* @access public
*/
this.build = () => {
self.action.build[self.name]();
}
/**
* @returns {number}
* @access public
*/
this.length = () => (cache || self.data || []).length;
constructor();
};
/** @type {Array.<string>} */
AnyankaKeys.Type.TYPES = [
"unknown", "string", "undefined", "null", "json", "utf8", "utf16",
"utf32", "bytes", "bool", "integer", "float", "custom"
];
/**
* @constructor
* @param {?Object.<string, number>} [inputs = null]
* @returns {void}
* @access public
*/
AnyankaKeys.BaseChange = function(inputs = null){
/** @type {number} */
this.FROM = (inputs || (inputs = {})).from || inputs.base_from || AnyankaKeys.SETTINGS.base_from;
/** @type {number} */
this.TO = inputs.to || inputs.base_to || AnyankaKeys.SETTINGS.base_to;
};
/**
* @constructor
* @param {?Object.<string, number>} [inputs = null]
* @returns {void}
* @access public
*/
AnyankaKeys.BaseChange.Parameters = function(inputs){
/** @type {AnyankaKeys.BaseChange.Parameters} */
const self = this;
/** @type {number} */
let i = 0;
/** @type {AnyankaKeys.BaseChange} */
this.BASE = new AnyankaKeys.BaseChange(inputs);
/** @type {number|null} */
this.summatory = null;
/**
* @returns {void}
* @access public
*/
this.go_to_next = () => {
self.summatory = (self.summatory || 0) / self.BASE.TO >> 0;
i ++;
};
/**
* @param {!number} value
* @returns {void}
* @access public
*/
this.add = value => {
self.summatory = (self.summatory || 0) * self.BASE.FROM + value;
};
/**
* @param {!anyanka_keys_convert_callback} callback
* @returns {void}
* @access public
*/
this.process = callback => {
if(self.summatory !== null)
while(self.summatory >= self.BASE.TO){
callback(self.summatory % self.BASE.TO, i);
self.go_to_next();
};
};
/**
* @param {!anyanka_keys_convert_callback} callback
* @returns {void}
* @access public
*/
this.end = callback => {
self.process(callback);
if(self.summatory !== null && (!i || self.summatory)){
callback(self.summatory, i);
self.go_to_next();
};
};
/**
* @param {!string} data
* @returns {number}
* @access public
*/
this.get_size = data => Math.round(data.length * Math.log2(self.BASE.FROM) / Math.log2(self.BASE.TO));
};
/**
* @param {!(any|null)} value
* @returns {boolean}
* @access public
* @static
*/
AnyankaKeys.is_dictionary = value => (
value !== undefined &&
value !== null &&
value.constructor == Object
);
/**
* @param {!string} string
* @param {!anyanka_keys_convert_callback} set
* @param {!AnyankaKeys.Options} options
* @returns {void}
* @access public
*/
AnyankaKeys.get_each_bytes_in_string = (string, set, options) => [...(
options.scape_uri ? encodeURIComponent(string) : string
)].forEach(character => {
/** @type {number} */
const code = character.charCodeAt(0),
/** @type {boolean} */
is_utf8 = (code & 0xFF) == code;
if(options.force_utf16)
[8, 0].forEach(wise => set((code >> wise) & 0xFF));
else if(options.scape){
if(code == options.scape_character)
[null, null].forEach(() => set(code));
else if(is_utf8){
set(code);
options.scape_utf8 && set(options.scape_character);
}else{
[8, 0].forEach(wise => set((code >> wise) & 0xFF));
options.scape_utf16 && set(options.scape_character);
};
}else
set(code);
});
/**
* @param {!(any|null)} data
* @param {!anyanka_keys_convert_callback} set
* @param {!AnyankaKeys.Options} options
* @returns {AnyankaKeys.Type}
* @access public
* @static
*/
AnyankaKeys.get_each_bytes = (data, set, options) => {
/** @type {AnyankaKeys.Type} */
let type = new AnyankaKeys.Type();
if(data === undefined)
type.set(2);
else if(data === null)
type.set(3);
else
switch(typeof data){
case "string":
AnyankaKeys.get_each_bytes_in_string(data, set, options);
type.set(1);
break;
case "boolean":
set(data ? 1 : 0);
type.set(9);
break;
case "number":
if(data == data >> 0){
let empties_done = false;
do{
set(data & 0xFF);
if(!empties_done){
if(data & 0xFF)
empties_done = true;
else
type.empties ++;
};
}while(data >>= 8);
type.set(10);
}else{
[...("" + data)].forEach(character => set(character.charCodeAt(0)));
type.set(11);
};
break;
case "object":
if(data instanceof Uint8Array){
type.set(5);
[...data].forEach(set);
}else if(data instanceof Uint16Array){
[...data].forEach(smallint => [0, 1].forEach(i => set((smallint >> i * 8) & 0xFF)));
type.set(6);
}else if(data instanceof Uint32Array){
[...data].forEach(integer => [0, 1, 2, 3].forEach(i => set((integer >> i * 8) & 0xFF)));
type.set(7);
}else if(data instanceof Array && !data.some(value => typeof value != "number" || value < 0 || value > 0xFF)){
data.forEach(set);
type.set(8);
}else if(["Array", "Object"].includes(data.constructor.name)){
AnyankaKeys.get_each_bytes_in_string(JSON.stringify(data), set, options);
// [...JSON.stringify(data)].forEach(character => set(character.charCodeAt(0)));
type.set(4);
}else{
type.set(12, data.constructor.name);
try{
AnyankaKeys.get_each_bytes_in_string(JSON.stringify(data), set, options);
// [...JSON.stringify(data)].forEach(character => set(character.charCodeAt(0)));
}catch(exception){
type.set(0);
};
};
break;
};
return type;
};
/**
* @param {!(number|Array.<number>)} data
* @param {!anyanka_keys_convert_callback} set
* @param {?(AnyankaKeys.BaseChange.Parameters|Object.<string, any|null>)} [parameters = null]
* @returns {void}
* @access public
* @static
*/
AnyankaKeys.change_base_iteration = (data, set, parameters = null) => {
(
!parameters ||
!(parameters instanceof AnyankaKeys.BaseChange.Parameters)
) && (parameters = new AnyankaKeys.BaseChange.Parameters(inputs));
(data instanceof Array ? data : [data]).forEach(value => {
parameters.add(value);
parameters.process(set);
});
};
/**
* @param {!(string|Array.<number>)} value
* @param {!number} to
* @param {?number} [from = null]
* @param {string|null} [type = null]
* @returns {string|Array.<number>|null}
* @access public
* @static
*/
AnyankaKeys.change_base = (value, to, from = null, type = null) => {
from || (from = AnyankaKeys.SETTINGS.base_from);
type || (type = (
typeof value == "number" && value == value >> 0 ? "integer" :
typeof value == "string" ? "string" :
value instanceof Array ? "array" :
"unknown"));
/** @type {string|Array.<number>|null} */
let response = null,
/** @type {anyanka_keys_convert_callback|null} */
set = null,
/** @type {anyanka_keys_default_callback|null} */
iterator = null;
/** @type {AnyankaKeys.BaseChange.Parameters} */
const parameters = new AnyankaKeys.BaseChange.Parameters({
/** @type {number} */
from : from,
/** @type {number} */
to : to
});
switch(type){
case "string":
response = "";
set = value => response = String.fromCharCode(value) + response;
iterator = () => [...value].map(character => AnyankaKeys.change_base_iteration(character.charCodeAt(0), set, parameters));
break;
case "array":
response = [];
set = value => response.unshift(value);
iterator = () => AnyankaKeys.change_base_iteration(value, set, parameters);
break;
};
if(response !== null){
iterator();
parameters.end(set);
};
return response;
};
return AnyankaKeys;
})();