Support alternative b64 characters
Coincidentally fixes #2 and fixes #7.
This commit is contained in:
parent
353937e3a1
commit
0e148a48ef
70
index.html
70
index.html
|
@ -55,7 +55,7 @@
|
|||
<a href="https://git.fwdekker.com/FWDekker/converter/src/branch/master/LICENSE">MIT License</a>.
|
||||
Source code available on <a href="https://git.fwdekker.com/FWDekker/converter/">git</a>.
|
||||
|
||||
<div style="float: right;">v1.4.4</div>
|
||||
<div style="float: right;">v1.4.5</div>
|
||||
</section>
|
||||
</footer>
|
||||
</main>
|
||||
|
@ -66,11 +66,40 @@
|
|||
<script src="https://cdnjs.cloudflare.com/ajax/libs/big-integer/1.6.44/BigInteger.min.js"
|
||||
integrity="sha256-es+ex6Oj344uak+VnCPyaHY2nzQkqhr7ByWVQgdjATA=" crossorigin="anonymous"></script>
|
||||
<script>
|
||||
const stringReplaceAt =
|
||||
(str, index, replacement) => str.substr(0, index) + replacement + str.substr(index + replacement.length);
|
||||
/**
|
||||
* Replaces the character at the given index with the given replacement.
|
||||
*
|
||||
* @param str the string to replace in
|
||||
* @param index the index in the given string to replace at
|
||||
* @param replacement the replacement to insert into the string
|
||||
* @returns {string} the input string with one character replaced
|
||||
*/
|
||||
const stringReplaceAt = (str, index, replacement) =>
|
||||
str.substr(0, index) + replacement + str.substr(index + replacement.length);
|
||||
|
||||
const stringReplaceAll =
|
||||
(str, target, replacement) => str.split(target).join(replacement);
|
||||
/**
|
||||
* Replaces all instances of the target with the replacement.
|
||||
*
|
||||
* @param str the string to replace in
|
||||
* @param target the character to replace
|
||||
* @param replacement the replacement to insert into the string
|
||||
* @returns {string} the input string with all instances of the target replaced
|
||||
*/
|
||||
const stringReplaceAll = (str, target, replacement) =>
|
||||
str.split(target).join(replacement);
|
||||
|
||||
/**
|
||||
* Runs `stringReplaceAll` for each character in `targets` and `replacements`.
|
||||
*
|
||||
* @param str the string to replace in
|
||||
* @param targets the characters to replace
|
||||
* @param replacements the replacements to insert into the string; each character here corresponds to a character
|
||||
* in the targets string
|
||||
* @returns {string} the input string with all instances of the targets replaced
|
||||
*/
|
||||
const stringReplaceAlls = (str, targets, replacements) =>
|
||||
Array.from(targets).reduce((output, target, index) =>
|
||||
stringReplaceAll(output, target, replacements[index]), str);
|
||||
|
||||
|
||||
class NumeralSystem {
|
||||
|
@ -117,7 +146,7 @@
|
|||
return;
|
||||
|
||||
this.textarea.value = this.numeralSystem.filterBaseString(this.textarea.value);
|
||||
updateAllInputs(this.numeralSystem.baseToDecimal(this.textarea.value));
|
||||
updateAllInputs(this, this.numeralSystem.baseToDecimal(this.textarea.value));
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -133,6 +162,17 @@
|
|||
}
|
||||
|
||||
class Base64NumeralSystem extends NumeralSystem {
|
||||
// TODO Convert static methods to static properties once supported by Firefox
|
||||
static defaultAlphabet() {
|
||||
return "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Constructs a new base 64 numeral system.
|
||||
*
|
||||
* @param alphabet the 64 characters to encode numbers with, and the padding character at the end
|
||||
*/
|
||||
constructor(alphabet) {
|
||||
super(64, alphabet, true);
|
||||
}
|
||||
|
@ -148,11 +188,14 @@
|
|||
.map(pair => String.fromCharCode(parseInt(pair.join(""), 16)))
|
||||
.join("");
|
||||
|
||||
return btoa(b64);
|
||||
return stringReplaceAlls(btoa(b64), Base64NumeralSystem.defaultAlphabet(), this.alphabet);
|
||||
}
|
||||
|
||||
baseToDecimal(baseString) {
|
||||
const hex = Array.from(atob(baseString))
|
||||
if (baseString.length % 4 === 1) throw new Error("Invalid input string length.");
|
||||
|
||||
const normalBaseString = stringReplaceAlls(baseString, this.alphabet, Base64NumeralSystem.defaultAlphabet());
|
||||
const hex = Array.from(atob(normalBaseString))
|
||||
.map(char => char.charCodeAt(0).toString(16).padStart(2, "0")).join("");
|
||||
return bigInt(hex, 16);
|
||||
}
|
||||
|
@ -160,17 +203,13 @@
|
|||
|
||||
class Base64NumeralSystemInput extends NumeralSystemInput {
|
||||
// TODO Convert static methods to static properties once supported by Firefox
|
||||
static defaultAlphabet() {
|
||||
return "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||
}
|
||||
|
||||
static dropdownOptions() {
|
||||
return {"Standard": ['+', '/'], "Filename": ['-', '_'], "IMAP": ['+', ',']};
|
||||
}
|
||||
|
||||
|
||||
constructor(name) {
|
||||
super(name, new Base64NumeralSystem(Base64NumeralSystemInput.defaultAlphabet()));
|
||||
super(name, new Base64NumeralSystem(Base64NumeralSystem.defaultAlphabet()));
|
||||
|
||||
this.dropdownLabel = document.createElement("label");
|
||||
this.dropdownLabel.setAttribute("for", `${this.name}Dropdown`);
|
||||
|
@ -236,8 +275,9 @@
|
|||
),
|
||||
];
|
||||
|
||||
const updateAllInputs = newValue => {
|
||||
const updateAllInputs = (source, newValue) => {
|
||||
for (const input of inputs)
|
||||
if (input !== source)
|
||||
input.update(newValue);
|
||||
};
|
||||
|
||||
|
@ -248,7 +288,7 @@
|
|||
for (const input of inputs)
|
||||
input.addToParent(inputParent);
|
||||
|
||||
updateAllInputs(bigInt(42));
|
||||
updateAllInputs(undefined, bigInt(42));
|
||||
inputs[0].textarea.focus();
|
||||
});
|
||||
</script>
|
||||
|
|
Loading…
Reference in New Issue