summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--std/encoding/base64url.ts45
-rw-r--r--std/encoding/base64url_test.ts42
2 files changed, 87 insertions, 0 deletions
diff --git a/std/encoding/base64url.ts b/std/encoding/base64url.ts
new file mode 100644
index 000000000..726ea2eb8
--- /dev/null
+++ b/std/encoding/base64url.ts
@@ -0,0 +1,45 @@
+// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
+
+import {
+ decode as convertBase64ToArrayBuffer,
+ encode as convertArrayBufferToBase64,
+} from "./base64.ts";
+
+/*
+ * Some variants allow or require omitting the padding '=' signs:
+ * https://en.wikipedia.org/wiki/Base64#URL_applications
+ */
+export function addPaddingToBase64url(base64url: string): string {
+ if (base64url.length % 4 === 2) return base64url + "==";
+ if (base64url.length % 4 === 3) return base64url + "=";
+ if (base64url.length % 4 === 1)
+ throw new TypeError("Illegal base64url string!");
+ return base64url;
+}
+
+function convertBase64urlToBase64(base64url: string): string {
+ return addPaddingToBase64url(base64url)
+ .replace(/\-/g, "+")
+ .replace(/_/g, "/");
+}
+
+function convertBase64ToBase64url(base64: string): string {
+ return base64.replace(/=/g, "").replace(/\+/g, "-").replace(/\//g, "_");
+}
+
+/**
+ * Converts given data with base64url encoding.
+ * Removes paddings '='.
+ * @param data input to encode
+ */
+export function encode(data: string | ArrayBuffer): string {
+ return convertBase64ToBase64url(convertArrayBufferToBase64(data));
+}
+
+/**
+ * Converts given base64url encoded data back to original
+ * @param data input to decode
+ */
+export function decode(data: string): ArrayBuffer {
+ return convertBase64ToArrayBuffer(convertBase64urlToBase64(data));
+}
diff --git a/std/encoding/base64url_test.ts b/std/encoding/base64url_test.ts
new file mode 100644
index 000000000..2af9096a4
--- /dev/null
+++ b/std/encoding/base64url_test.ts
@@ -0,0 +1,42 @@
+// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
+
+const { test } = Deno;
+import { assertEquals } from "../testing/asserts.ts";
+import { encode, decode } from "./base64url.ts";
+
+const testsetString = [
+ ["", ""],
+ ["f", "Zg"],
+ ["fo", "Zm8"],
+ ["foo", "Zm9v"],
+ ["foob", "Zm9vYg"],
+ ["fooba", "Zm9vYmE"],
+ ["foobar", "Zm9vYmFy"],
+ [">?>d?ß", "Pj8-ZD_f"],
+];
+
+const testsetBinary = [
+ [new TextEncoder().encode("\x00"), "AA"],
+ [new TextEncoder().encode("\x00\x00"), "AAA"],
+ [new TextEncoder().encode("\x00\x00\x00"), "AAAA"],
+ [new TextEncoder().encode("\x00\x00\x00\x00"), "AAAAAA"],
+];
+
+test("[encoding/base64url] testBase64urlEncodeString", () => {
+ for (const [input, output] of testsetString) {
+ assertEquals(encode(input), output);
+ }
+});
+
+test("[encoding/base64url] testBase64urlEncodeBinary", () => {
+ for (const [input, output] of testsetBinary) {
+ assertEquals(encode(input), output);
+ }
+});
+
+test("[encoding/base64ur] testBase64urDecodeBinary", () => {
+ for (const [input, output] of testsetBinary) {
+ const outputBinary = new Uint8Array(decode(output as string));
+ assertEquals(outputBinary, input as Uint8Array);
+ }
+});