From 5fb57639b731eaa1a5e7a6ec694c1ccd72a03a0b Mon Sep 17 00:00:00 2001 From: takker99 <37929109+takker99@users.noreply.github.com> Date: Tue, 6 Aug 2024 16:24:58 +0900 Subject: [PATCH] refactor: Remove `std/hash` from `vendor/` and Organize `scrapbox-userscript-websocket` roughly --- .../websocket/@types/socket-io}/emitter.ts | 0 .../websocket/@types/socket-io}/index.ts | 4 +- .../websocket/@types/socket-io}/manager.ts | 8 +- .../websocket/@types/socket-io}/parser.ts | 0 .../websocket/@types/socket-io}/socket.ts | 12 +- .../@types/socket-io}/typed-events.ts | 0 browser/websocket/applyCommit.ts | 2 +- browser/websocket/diffToChanges.ts | 2 +- browser/websocket/listen.ts | 4 +- browser/websocket/makeChanges.ts | 2 +- browser/websocket/patch.ts | 2 +- browser/websocket/pin.ts | 2 +- browser/websocket/push.ts | 2 +- .../websocket/socket-io.ts | 2 +- browser/websocket/socket.ts | 4 +- browser/websocket/updateCodeBlock.ts | 2 +- browser/websocket/updateCodeFile.ts | 2 +- .../websocket/websocket-types.ts | 0 .../0.2.4/mod.ts => browser/websocket/wrap.ts | 24 +- deno.jsonc | 4 +- deno.lock | 10 + deps/socket.ts | 1 - rest/uploadToGCS.ts | 9 +- vendor/deno.land/std@0.160.0/encoding/hex.ts | 67 ----- vendor/deno.land/std@0.160.0/hash/md5.ts | 251 ------------------ 25 files changed, 54 insertions(+), 362 deletions(-) rename {vendor/raw.githubusercontent.com/takker99/scrapbox-userscript-websocket/0.2.4/types/socketIO => browser/websocket/@types/socket-io}/emitter.ts (100%) rename {vendor/raw.githubusercontent.com/takker99/scrapbox-userscript-websocket/0.2.4/types/socketIO => browser/websocket/@types/socket-io}/index.ts (90%) rename {vendor/raw.githubusercontent.com/takker99/scrapbox-userscript-websocket/0.2.4/types/socketIO => browser/websocket/@types/socket-io}/manager.ts (98%) rename {vendor/raw.githubusercontent.com/takker99/scrapbox-userscript-websocket/0.2.4/types/socketIO => browser/websocket/@types/socket-io}/parser.ts (100%) rename {vendor/raw.githubusercontent.com/takker99/scrapbox-userscript-websocket/0.2.4/types/socketIO => browser/websocket/@types/socket-io}/socket.ts (96%) rename {vendor/raw.githubusercontent.com/takker99/scrapbox-userscript-websocket/0.2.4/types/socketIO => browser/websocket/@types/socket-io}/typed-events.ts (100%) rename vendor/raw.githubusercontent.com/takker99/scrapbox-userscript-websocket/0.2.4/socket.ts => browser/websocket/socket-io.ts (97%) rename vendor/raw.githubusercontent.com/takker99/scrapbox-userscript-websocket/0.2.4/types.ts => browser/websocket/websocket-types.ts (100%) rename vendor/raw.githubusercontent.com/takker99/scrapbox-userscript-websocket/0.2.4/mod.ts => browser/websocket/wrap.ts (92%) delete mode 100644 deps/socket.ts delete mode 100644 vendor/deno.land/std@0.160.0/encoding/hex.ts delete mode 100644 vendor/deno.land/std@0.160.0/hash/md5.ts diff --git a/vendor/raw.githubusercontent.com/takker99/scrapbox-userscript-websocket/0.2.4/types/socketIO/emitter.ts b/browser/websocket/@types/socket-io/emitter.ts similarity index 100% rename from vendor/raw.githubusercontent.com/takker99/scrapbox-userscript-websocket/0.2.4/types/socketIO/emitter.ts rename to browser/websocket/@types/socket-io/emitter.ts diff --git a/vendor/raw.githubusercontent.com/takker99/scrapbox-userscript-websocket/0.2.4/types/socketIO/index.ts b/browser/websocket/@types/socket-io/index.ts similarity index 90% rename from vendor/raw.githubusercontent.com/takker99/scrapbox-userscript-websocket/0.2.4/types/socketIO/index.ts rename to browser/websocket/@types/socket-io/index.ts index c12b106..7cca320 100644 --- a/vendor/raw.githubusercontent.com/takker99/scrapbox-userscript-websocket/0.2.4/types/socketIO/index.ts +++ b/browser/websocket/@types/socket-io/index.ts @@ -1,6 +1,6 @@ // this file is copied from https://cdn.esm.sh/v54/socket.io-client@4.2.0/build/index.d.ts -import { ManagerOptions } from "./manager.ts"; -import { Socket, SocketOptions } from "./socket.ts"; +import type { ManagerOptions } from "./manager.ts"; +import type { Socket, SocketOptions } from "./socket.ts"; /** * Looks up an existing `Manager` for multiplexing. * If the user summons: diff --git a/vendor/raw.githubusercontent.com/takker99/scrapbox-userscript-websocket/0.2.4/types/socketIO/manager.ts b/browser/websocket/@types/socket-io/manager.ts similarity index 98% rename from vendor/raw.githubusercontent.com/takker99/scrapbox-userscript-websocket/0.2.4/types/socketIO/manager.ts rename to browser/websocket/@types/socket-io/manager.ts index 5270161..85a4065 100644 --- a/vendor/raw.githubusercontent.com/takker99/scrapbox-userscript-websocket/0.2.4/types/socketIO/manager.ts +++ b/browser/websocket/@types/socket-io/manager.ts @@ -1,10 +1,10 @@ // this file is copied from https://cdn.esm.sh/v54/socket.io-client@4.2.0/build/manager.d.ts // deno-lint-ignore-file no-explicit-any camelcase ban-types -import { Socket, SocketOptions } from "./socket.ts"; -import { Packet } from "./parser.ts"; +import type { Socket, SocketOptions } from "./socket.ts"; +import type { Packet } from "./parser.ts"; import { - DefaultEventsMap, - EventsMap, + type DefaultEventsMap, + type EventsMap, StrictEventEmitter, } from "./typed-events.ts"; interface EngineOptions { diff --git a/vendor/raw.githubusercontent.com/takker99/scrapbox-userscript-websocket/0.2.4/types/socketIO/parser.ts b/browser/websocket/@types/socket-io/parser.ts similarity index 100% rename from vendor/raw.githubusercontent.com/takker99/scrapbox-userscript-websocket/0.2.4/types/socketIO/parser.ts rename to browser/websocket/@types/socket-io/parser.ts diff --git a/vendor/raw.githubusercontent.com/takker99/scrapbox-userscript-websocket/0.2.4/types/socketIO/socket.ts b/browser/websocket/@types/socket-io/socket.ts similarity index 96% rename from vendor/raw.githubusercontent.com/takker99/scrapbox-userscript-websocket/0.2.4/types/socketIO/socket.ts rename to browser/websocket/@types/socket-io/socket.ts index 3342860..916a852 100644 --- a/vendor/raw.githubusercontent.com/takker99/scrapbox-userscript-websocket/0.2.4/types/socketIO/socket.ts +++ b/browser/websocket/@types/socket-io/socket.ts @@ -1,12 +1,12 @@ // deno-lint-ignore-file no-explicit-any camelcase // this file is copied from https://cdn.esm.sh/v54/socket.io-client@4.2.0/build/socket.d.ts -import { Packet } from "./parser.ts"; -import { Manager } from "./manager.ts"; +import type { Packet } from "./parser.ts"; +import type { Manager } from "./manager.ts"; import { - DefaultEventsMap, - EventNames, - EventParams, - EventsMap, + type DefaultEventsMap, + type EventNames, + type EventParams, + type EventsMap, StrictEventEmitter, } from "./typed-events.ts"; export interface SocketOptions { diff --git a/vendor/raw.githubusercontent.com/takker99/scrapbox-userscript-websocket/0.2.4/types/socketIO/typed-events.ts b/browser/websocket/@types/socket-io/typed-events.ts similarity index 100% rename from vendor/raw.githubusercontent.com/takker99/scrapbox-userscript-websocket/0.2.4/types/socketIO/typed-events.ts rename to browser/websocket/@types/socket-io/typed-events.ts diff --git a/browser/websocket/applyCommit.ts b/browser/websocket/applyCommit.ts index 0a1db24..6ecd030 100644 --- a/browser/websocket/applyCommit.ts +++ b/browser/websocket/applyCommit.ts @@ -1,4 +1,4 @@ -import type { CommitNotification } from "../../deps/socket.ts"; +import type { CommitNotification } from "./websocket-types.ts"; import type { Page } from "@cosense/types/rest"; import { getUnixTimeFromId } from "./id.ts"; type Line = Page["lines"][number]; diff --git a/browser/websocket/diffToChanges.ts b/browser/websocket/diffToChanges.ts index dc71094..0133495 100644 --- a/browser/websocket/diffToChanges.ts +++ b/browser/websocket/diffToChanges.ts @@ -4,7 +4,7 @@ import type { DeleteChange, InsertChange, UpdateChange, -} from "../../deps/socket.ts"; +} from "./websocket-types.ts"; import { createNewLineId } from "./id.ts"; type Options = { diff --git a/browser/websocket/listen.ts b/browser/websocket/listen.ts index 230f5ca..66766db 100644 --- a/browser/websocket/listen.ts +++ b/browser/websocket/listen.ts @@ -10,7 +10,7 @@ import { type Socket, socketIO, wrap, -} from "../../deps/socket.ts"; +} from "./wrap.ts"; import type { HTTPError } from "../../rest/responseIntoResult.ts"; import type { AbortError, NetworkError } from "../../rest/robustFetch.ts"; import { getProjectId } from "./pull.ts"; @@ -18,7 +18,7 @@ import { connect, disconnect } from "./socket.ts"; export type { ProjectUpdatesStreamCommit, ProjectUpdatesStreamEvent, -} from "../../deps/socket.ts"; +} from "./websocket-types.ts"; export interface ListenStreamOptions { socket?: Socket; diff --git a/browser/websocket/makeChanges.ts b/browser/websocket/makeChanges.ts index 74581ee..ae748b6 100644 --- a/browser/websocket/makeChanges.ts +++ b/browser/websocket/makeChanges.ts @@ -1,6 +1,6 @@ import { diffToChanges } from "./diffToChanges.ts"; import type { Page } from "@cosense/types/rest"; -import type { Change } from "../../deps/socket.ts"; +import type { Change } from "./websocket-types.ts"; import { findMetadata, getHelpfeels } from "./findMetadata.ts"; import { isSameArray } from "./isSameArray.ts"; diff --git a/browser/websocket/patch.ts b/browser/websocket/patch.ts index a8a9532..b819fc5 100644 --- a/browser/websocket/patch.ts +++ b/browser/websocket/patch.ts @@ -1,4 +1,4 @@ -import type { Change, DeletePageChange, PinChange } from "../../deps/socket.ts"; +import type { Change, DeletePageChange, PinChange } from "./wrap.ts"; import { makeChanges } from "./makeChanges.ts"; import type { Page } from "@cosense/types/rest"; import { push, type PushError, type PushOptions } from "./push.ts"; diff --git a/browser/websocket/pin.ts b/browser/websocket/pin.ts index 7557975..9be4685 100644 --- a/browser/websocket/pin.ts +++ b/browser/websocket/pin.ts @@ -1,5 +1,5 @@ import type { Result } from "option-t/plain_result"; -import type { Change, Socket } from "../../deps/socket.ts"; +import type { Change, Socket } from "./wrap.ts"; import { push, type PushError, type PushOptions } from "./push.ts"; export interface PinOptions extends PushOptions { diff --git a/browser/websocket/push.ts b/browser/websocket/push.ts index c2a0747..aceb6f7 100644 --- a/browser/websocket/push.ts +++ b/browser/websocket/push.ts @@ -10,7 +10,7 @@ import { socketIO, type TimeoutError, wrap, -} from "../../deps/socket.ts"; +} from "./wrap.ts"; import { connect, disconnect } from "./socket.ts"; import { pull } from "./pull.ts"; import type { diff --git a/vendor/raw.githubusercontent.com/takker99/scrapbox-userscript-websocket/0.2.4/socket.ts b/browser/websocket/socket-io.ts similarity index 97% rename from vendor/raw.githubusercontent.com/takker99/scrapbox-userscript-websocket/0.2.4/socket.ts rename to browser/websocket/socket-io.ts index 915b259..8fb5652 100644 --- a/vendor/raw.githubusercontent.com/takker99/scrapbox-userscript-websocket/0.2.4/socket.ts +++ b/browser/websocket/socket-io.ts @@ -3,7 +3,7 @@ import type { ManagerOptions, Socket, SocketOptions, -} from "./types/socketIO/index.ts"; +} from "./@types/socket-io/index.ts"; export type { Manager, ManagerOptions, Socket, SocketOptions }; export const socketIO = async (): Promise => { diff --git a/browser/websocket/socket.ts b/browser/websocket/socket.ts index fbaa733..02a7481 100644 --- a/browser/websocket/socket.ts +++ b/browser/websocket/socket.ts @@ -1,5 +1,5 @@ -import { type Socket, socketIO } from "../../deps/socket.ts"; -export type { Socket } from "../../deps/socket.ts"; +import { type Socket, socketIO } from "./socket-io.ts"; +export type { Socket } from "./socket-io.ts"; /** 新しいsocketを作る */ export const makeSocket = (): Promise => socketIO(); diff --git a/browser/websocket/updateCodeBlock.ts b/browser/websocket/updateCodeBlock.ts index f0db325..802ef37 100644 --- a/browser/websocket/updateCodeBlock.ts +++ b/browser/websocket/updateCodeBlock.ts @@ -3,7 +3,7 @@ import type { DeleteChange, InsertChange, UpdateChange, -} from "../../deps/socket.ts"; +} from "./websocket-types.ts"; import type { TinyCodeBlock } from "../../rest/getCodeBlocks.ts"; import { diffToChanges } from "./diffToChanges.ts"; import { isSimpleCodeFile } from "./isSimpleCodeFile.ts"; diff --git a/browser/websocket/updateCodeFile.ts b/browser/websocket/updateCodeFile.ts index 4a8f0f8..a6722f3 100644 --- a/browser/websocket/updateCodeFile.ts +++ b/browser/websocket/updateCodeFile.ts @@ -3,7 +3,7 @@ import type { DeleteChange, InsertChange, UpdateChange, -} from "../../deps/socket.ts"; +} from "./websocket-types.ts"; import { getCodeBlocks, type TinyCodeBlock } from "../../rest/getCodeBlocks.ts"; import { createNewLineId } from "./id.ts"; import { diff, toExtendedChanges } from "../../deps/onp.ts"; diff --git a/vendor/raw.githubusercontent.com/takker99/scrapbox-userscript-websocket/0.2.4/types.ts b/browser/websocket/websocket-types.ts similarity index 100% rename from vendor/raw.githubusercontent.com/takker99/scrapbox-userscript-websocket/0.2.4/types.ts rename to browser/websocket/websocket-types.ts diff --git a/vendor/raw.githubusercontent.com/takker99/scrapbox-userscript-websocket/0.2.4/mod.ts b/browser/websocket/wrap.ts similarity index 92% rename from vendor/raw.githubusercontent.com/takker99/scrapbox-userscript-websocket/0.2.4/mod.ts rename to browser/websocket/wrap.ts index 8f383bb..2afe064 100644 --- a/vendor/raw.githubusercontent.com/takker99/scrapbox-userscript-websocket/0.2.4/mod.ts +++ b/browser/websocket/wrap.ts @@ -1,17 +1,17 @@ -import type { Socket } from "./socket.ts"; +import type { Socket } from "./socket-io.ts"; import { - DataOf, - EventMap, - FailedResOf, + type DataOf, + type EventMap, + type FailedResOf, isPageCommitError, - ListenEventMap, - Result, - SuccessResOf, - TimeoutError, - UnexpectedError, -} from "./types.ts"; -export * from "./types.ts"; -export * from "./socket.ts"; + type ListenEventMap, + type Result, + type SuccessResOf, + type TimeoutError, + type UnexpectedError, +} from "./websocket-types.ts"; +export * from "./websocket-types.ts"; +export * from "./socket-io.ts"; export interface SocketOperator { request: ( diff --git a/deno.jsonc b/deno.jsonc index 7143942..f817252 100644 --- a/deno.jsonc +++ b/deno.jsonc @@ -16,10 +16,10 @@ "@progfay/scrapbox-parser": "jsr:@progfay/scrapbox-parser@9", "@std/assert": "jsr:@std/assert@1", "@std/async": "jsr:@std/async@1", - "@std/hash": "./vendor/deno.land/std@0.160.0/hash/md5.ts", + "@std/encoding": "jsr:@std/encoding@1", + "@takker/md5": "jsr:@takker/md5@0.1", "@std/testing/snapshot": "jsr:@std/testing@0/snapshot", "@takker/onp": "./vendor/raw.githubusercontent.com/takker99/onp/0.0.1/mod.ts", - "@takker/scrapbox-userscript-websocket": "./vendor/raw.githubusercontent.com/takker99/scrapbox-userscript-websocket/0.2.4/mod.ts", "option-t": "npm:option-t@^49.1.0" }, "exports": { diff --git a/deno.lock b/deno.lock index 7ad02f0..2656eea 100644 --- a/deno.lock +++ b/deno.lock @@ -8,6 +8,7 @@ "jsr:@std/assert@1": "jsr:@std/assert@1.0.1", "jsr:@std/assert@1.0.0-rc.2": "jsr:@std/assert@1.0.0-rc.2", "jsr:@std/async@1": "jsr:@std/async@1.0.1", + "jsr:@std/encoding@1": "jsr:@std/encoding@1.0.1", "jsr:@std/fmt@^0.225.4": "jsr:@std/fmt@0.225.6", "jsr:@std/fs@^1.0.0-rc.1": "jsr:@std/fs@1.0.0", "jsr:@std/internal@^1.0.0": "jsr:@std/internal@1.0.1", @@ -15,6 +16,7 @@ "jsr:@std/path@1.0.0-rc.2": "jsr:@std/path@1.0.0-rc.2", "jsr:@std/path@^1.0.2": "jsr:@std/path@1.0.2", "jsr:@std/testing@0": "jsr:@std/testing@0.225.3", + "jsr:@takker/md5@0.1": "jsr:@takker/md5@0.1.0", "npm:option-t@^49.1.0": "npm:option-t@49.1.0" }, "jsr": { @@ -39,6 +41,9 @@ "@std/async@1.0.1": { "integrity": "3c7f6324a8a1b47ca657e5a349b511c9a6c2c0729e9d66b223c9ecaac0753ecb" }, + "@std/encoding@1.0.1": { + "integrity": "5955c6c542ebb4ce6587c3b548dc71e07a6c27614f1976d1d3887b1196cf4e65" + }, "@std/fmt@0.225.6": { "integrity": "aba6aea27f66813cecfd9484e074a9e9845782ab0685c030e453a8a70b37afc8" }, @@ -66,6 +71,9 @@ "jsr:@std/internal@^1.0.0", "jsr:@std/path@1.0.0-rc.2" ] + }, + "@takker/md5@0.1.0": { + "integrity": "4c423d8247aadf7bcb1eb83c727bf28c05c21906e916517395d00aa157b6eae0" } }, "npm": { @@ -209,7 +217,9 @@ "jsr:@progfay/scrapbox-parser@9", "jsr:@std/assert@1", "jsr:@std/async@1", + "jsr:@std/encoding@1", "jsr:@std/testing@0", + "jsr:@takker/md5@0.1", "npm:option-t@^49.1.0" ] } diff --git a/deps/socket.ts b/deps/socket.ts deleted file mode 100644 index 29a67ed..0000000 --- a/deps/socket.ts +++ /dev/null @@ -1 +0,0 @@ -export * from "@takker/scrapbox-userscript-websocket"; diff --git a/rest/uploadToGCS.ts b/rest/uploadToGCS.ts index 77173bc..00d6f0a 100644 --- a/rest/uploadToGCS.ts +++ b/rest/uploadToGCS.ts @@ -5,7 +5,8 @@ import { setDefaults, } from "./options.ts"; import type { ErrorLike, NotFoundError } from "@cosense/types/rest"; -import { Md5 } from "@std/hash"; +import { md5 } from "@takker/md5"; +import { encodeHex } from "@std/encoding/hex"; import { createOk, isErr, @@ -46,14 +47,14 @@ export const uploadToGCS = async ( projectId: string, options?: ExtendedOptions, ): Promise> => { - const md5 = `${new Md5().update(await file.arrayBuffer())}`; - const res = await uploadRequest(file, projectId, md5, options); + const md5Hash = `${encodeHex(md5(await file.arrayBuffer()))}`; + const res = await uploadRequest(file, projectId, md5Hash, options); if (isErr(res)) return res; const fileOrRequest = unwrapOk(res); if ("embedUrl" in fileOrRequest) return createOk(fileOrRequest); const result = await upload(fileOrRequest.signedUrl, file, options); if (isErr(result)) return result; - return verify(projectId, fileOrRequest.fileId, md5, options); + return verify(projectId, fileOrRequest.fileId, md5Hash, options); }; /** 容量を使い切ったときに発生するerror */ diff --git a/vendor/deno.land/std@0.160.0/encoding/hex.ts b/vendor/deno.land/std@0.160.0/encoding/hex.ts deleted file mode 100644 index b23c857..0000000 --- a/vendor/deno.land/std@0.160.0/encoding/hex.ts +++ /dev/null @@ -1,67 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// https://github.com/golang/go/blob/master/LICENSE -// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license. - -/** Port of the Go - * [encoding/hex](https://github.com/golang/go/blob/go1.12.5/src/encoding/hex/hex.go) - * library. - * - * This module is browser compatible. - * - * @module - */ - -const hexTable = new TextEncoder().encode("0123456789abcdef"); - -function errInvalidByte(byte: number) { - return new TypeError(`Invalid byte '${String.fromCharCode(byte)}'`); -} - -function errLength() { - return new RangeError("Odd length hex string"); -} - -/** Converts a hex character into its value. */ -function fromHexChar(byte: number): number { - // '0' <= byte && byte <= '9' - if (48 <= byte && byte <= 57) return byte - 48; - // 'a' <= byte && byte <= 'f' - if (97 <= byte && byte <= 102) return byte - 97 + 10; - // 'A' <= byte && byte <= 'F' - if (65 <= byte && byte <= 70) return byte - 65 + 10; - - throw errInvalidByte(byte); -} - -/** Encodes `src` into `src.length * 2` bytes. */ -export function encode(src: Uint8Array): Uint8Array { - const dst = new Uint8Array(src.length * 2); - for (let i = 0; i < dst.length; i++) { - const v = src[i]; - dst[i * 2] = hexTable[v >> 4]; - dst[i * 2 + 1] = hexTable[v & 0x0f]; - } - return dst; -} - -/** - * Decodes `src` into `src.length / 2` bytes. - * If the input is malformed, an error will be thrown. - */ -export function decode(src: Uint8Array): Uint8Array { - const dst = new Uint8Array(src.length / 2); - for (let i = 0; i < dst.length; i++) { - const a = fromHexChar(src[i * 2]); - const b = fromHexChar(src[i * 2 + 1]); - dst[i] = (a << 4) | b; - } - - if (src.length % 2 == 1) { - // Check for invalid char before reporting bad length, - // since the invalid char (if present) is an earlier problem. - fromHexChar(src[dst.length * 2]); - throw errLength(); - } - - return dst; -} diff --git a/vendor/deno.land/std@0.160.0/hash/md5.ts b/vendor/deno.land/std@0.160.0/hash/md5.ts deleted file mode 100644 index 0bd2dd4..0000000 --- a/vendor/deno.land/std@0.160.0/hash/md5.ts +++ /dev/null @@ -1,251 +0,0 @@ -// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license. -// This module is browser compatible. - -import * as hex from "../encoding/hex.ts"; - -const TYPE_ERROR_MSG = "md5: `data` is invalid type"; -const BLOCK_SIZE = 64; - -export type Message = string | ArrayBuffer; - -/** Md5 hash */ -export class Md5 { - #a: number; - #b: number; - #c: number; - #d: number; - #block: Uint8Array; - #pos: number; - #n0: number; - #n1: number; - - constructor() { - this.#a = 0x67452301; - this.#b = 0xefcdab89; - this.#c = 0x98badcfe; - this.#d = 0x10325476; - this.#block = new Uint8Array(BLOCK_SIZE); - this.#pos = 0; - this.#n0 = 0; - this.#n1 = 0; - } - - #addLength(len: number) { - let n0 = this.#n0; - n0 += len; - if (n0 > 0xffffffff) this.#n1 += 1; - this.#n0 = n0 >>> 0; - } - - #hash(block: Uint8Array) { - let a = this.#a; - let b = this.#b; - let c = this.#c; - let d = this.#d; - - const blk = (i: number): number => - block[i] | - (block[i + 1] << 8) | - (block[i + 2] << 16) | - (block[i + 3] << 24); - - const rol32 = (x: number, n: number): number => (x << n) | (x >>> (32 - n)); - - const x0 = blk(0); - const x1 = blk(4); - const x2 = blk(8); - const x3 = blk(12); - const x4 = blk(16); - const x5 = blk(20); - const x6 = blk(24); - const x7 = blk(28); - const x8 = blk(32); - const x9 = blk(36); - const xa = blk(40); - const xb = blk(44); - const xc = blk(48); - const xd = blk(52); - const xe = blk(56); - const xf = blk(60); - - // round 1 - a = b + rol32((((c ^ d) & b) ^ d) + a + x0 + 0xd76aa478, 7); - d = a + rol32((((b ^ c) & a) ^ c) + d + x1 + 0xe8c7b756, 12); - c = d + rol32((((a ^ b) & d) ^ b) + c + x2 + 0x242070db, 17); - b = c + rol32((((d ^ a) & c) ^ a) + b + x3 + 0xc1bdceee, 22); - a = b + rol32((((c ^ d) & b) ^ d) + a + x4 + 0xf57c0faf, 7); - d = a + rol32((((b ^ c) & a) ^ c) + d + x5 + 0x4787c62a, 12); - c = d + rol32((((a ^ b) & d) ^ b) + c + x6 + 0xa8304613, 17); - b = c + rol32((((d ^ a) & c) ^ a) + b + x7 + 0xfd469501, 22); - a = b + rol32((((c ^ d) & b) ^ d) + a + x8 + 0x698098d8, 7); - d = a + rol32((((b ^ c) & a) ^ c) + d + x9 + 0x8b44f7af, 12); - c = d + rol32((((a ^ b) & d) ^ b) + c + xa + 0xffff5bb1, 17); - b = c + rol32((((d ^ a) & c) ^ a) + b + xb + 0x895cd7be, 22); - a = b + rol32((((c ^ d) & b) ^ d) + a + xc + 0x6b901122, 7); - d = a + rol32((((b ^ c) & a) ^ c) + d + xd + 0xfd987193, 12); - c = d + rol32((((a ^ b) & d) ^ b) + c + xe + 0xa679438e, 17); - b = c + rol32((((d ^ a) & c) ^ a) + b + xf + 0x49b40821, 22); - - // round 2 - a = b + rol32((((b ^ c) & d) ^ c) + a + x1 + 0xf61e2562, 5); - d = a + rol32((((a ^ b) & c) ^ b) + d + x6 + 0xc040b340, 9); - c = d + rol32((((d ^ a) & b) ^ a) + c + xb + 0x265e5a51, 14); - b = c + rol32((((c ^ d) & a) ^ d) + b + x0 + 0xe9b6c7aa, 20); - a = b + rol32((((b ^ c) & d) ^ c) + a + x5 + 0xd62f105d, 5); - d = a + rol32((((a ^ b) & c) ^ b) + d + xa + 0x02441453, 9); - c = d + rol32((((d ^ a) & b) ^ a) + c + xf + 0xd8a1e681, 14); - b = c + rol32((((c ^ d) & a) ^ d) + b + x4 + 0xe7d3fbc8, 20); - a = b + rol32((((b ^ c) & d) ^ c) + a + x9 + 0x21e1cde6, 5); - d = a + rol32((((a ^ b) & c) ^ b) + d + xe + 0xc33707d6, 9); - c = d + rol32((((d ^ a) & b) ^ a) + c + x3 + 0xf4d50d87, 14); - b = c + rol32((((c ^ d) & a) ^ d) + b + x8 + 0x455a14ed, 20); - a = b + rol32((((b ^ c) & d) ^ c) + a + xd + 0xa9e3e905, 5); - d = a + rol32((((a ^ b) & c) ^ b) + d + x2 + 0xfcefa3f8, 9); - c = d + rol32((((d ^ a) & b) ^ a) + c + x7 + 0x676f02d9, 14); - b = c + rol32((((c ^ d) & a) ^ d) + b + xc + 0x8d2a4c8a, 20); - - // round 3 - a = b + rol32((b ^ c ^ d) + a + x5 + 0xfffa3942, 4); - d = a + rol32((a ^ b ^ c) + d + x8 + 0x8771f681, 11); - c = d + rol32((d ^ a ^ b) + c + xb + 0x6d9d6122, 16); - b = c + rol32((c ^ d ^ a) + b + xe + 0xfde5380c, 23); - a = b + rol32((b ^ c ^ d) + a + x1 + 0xa4beea44, 4); - d = a + rol32((a ^ b ^ c) + d + x4 + 0x4bdecfa9, 11); - c = d + rol32((d ^ a ^ b) + c + x7 + 0xf6bb4b60, 16); - b = c + rol32((c ^ d ^ a) + b + xa + 0xbebfbc70, 23); - a = b + rol32((b ^ c ^ d) + a + xd + 0x289b7ec6, 4); - d = a + rol32((a ^ b ^ c) + d + x0 + 0xeaa127fa, 11); - c = d + rol32((d ^ a ^ b) + c + x3 + 0xd4ef3085, 16); - b = c + rol32((c ^ d ^ a) + b + x6 + 0x04881d05, 23); - a = b + rol32((b ^ c ^ d) + a + x9 + 0xd9d4d039, 4); - d = a + rol32((a ^ b ^ c) + d + xc + 0xe6db99e5, 11); - c = d + rol32((d ^ a ^ b) + c + xf + 0x1fa27cf8, 16); - b = c + rol32((c ^ d ^ a) + b + x2 + 0xc4ac5665, 23); - - // round 4 - a = b + rol32((c ^ (b | ~d)) + a + x0 + 0xf4292244, 6); - d = a + rol32((b ^ (a | ~c)) + d + x7 + 0x432aff97, 10); - c = d + rol32((a ^ (d | ~b)) + c + xe + 0xab9423a7, 15); - b = c + rol32((d ^ (c | ~a)) + b + x5 + 0xfc93a039, 21); - a = b + rol32((c ^ (b | ~d)) + a + xc + 0x655b59c3, 6); - d = a + rol32((b ^ (a | ~c)) + d + x3 + 0x8f0ccc92, 10); - c = d + rol32((a ^ (d | ~b)) + c + xa + 0xffeff47d, 15); - b = c + rol32((d ^ (c | ~a)) + b + x1 + 0x85845dd1, 21); - a = b + rol32((c ^ (b | ~d)) + a + x8 + 0x6fa87e4f, 6); - d = a + rol32((b ^ (a | ~c)) + d + xf + 0xfe2ce6e0, 10); - c = d + rol32((a ^ (d | ~b)) + c + x6 + 0xa3014314, 15); - b = c + rol32((d ^ (c | ~a)) + b + xd + 0x4e0811a1, 21); - a = b + rol32((c ^ (b | ~d)) + a + x4 + 0xf7537e82, 6); - d = a + rol32((b ^ (a | ~c)) + d + xb + 0xbd3af235, 10); - c = d + rol32((a ^ (d | ~b)) + c + x2 + 0x2ad7d2bb, 15); - b = c + rol32((d ^ (c | ~a)) + b + x9 + 0xeb86d391, 21); - - this.#a = (this.#a + a) >>> 0; - this.#b = (this.#b + b) >>> 0; - this.#c = (this.#c + c) >>> 0; - this.#d = (this.#d + d) >>> 0; - } - - /** - * Update internal state - * @param data data to update, data cannot exceed 2^32 bytes - */ - update(data: Message): this { - let msg: Uint8Array; - - if (typeof data === "string") { - msg = new TextEncoder().encode(data as string); - } else if (typeof data === "object") { - if (data instanceof ArrayBuffer || ArrayBuffer.isView(data)) { - msg = new Uint8Array(data); - } else { - throw new TypeError(TYPE_ERROR_MSG); - } - } else { - throw new TypeError(TYPE_ERROR_MSG); - } - - let pos = this.#pos; - const free = BLOCK_SIZE - pos; - - if (msg.length < free) { - this.#block.set(msg, pos); - pos += msg.length; - } else { - // hash first block - this.#block.set(msg.slice(0, free), pos); - this.#hash(this.#block); - - // hash as many blocks as possible - let i = free; - while (i + BLOCK_SIZE <= msg.length) { - this.#hash(msg.slice(i, i + BLOCK_SIZE)); - i += BLOCK_SIZE; - } - - // store leftover - this.#block.fill(0).set(msg.slice(i), 0); - pos = msg.length - i; - } - - this.#pos = pos; - this.#addLength(msg.length); - - return this; - } - - /** Returns final hash */ - digest(): ArrayBuffer { - let padLen = BLOCK_SIZE - this.#pos; - if (padLen < 9) padLen += BLOCK_SIZE; - - const pad = new Uint8Array(padLen); - - pad[0] = 0x80; - - const n0 = this.#n0 << 3; - const n1 = (this.#n1 << 3) | (this.#n0 >>> 29); - pad[pad.length - 8] = n0 & 0xff; - pad[pad.length - 7] = (n0 >>> 8) & 0xff; - pad[pad.length - 6] = (n0 >>> 16) & 0xff; - pad[pad.length - 5] = (n0 >>> 24) & 0xff; - pad[pad.length - 4] = n1 & 0xff; - pad[pad.length - 3] = (n1 >>> 8) & 0xff; - pad[pad.length - 2] = (n1 >>> 16) & 0xff; - pad[pad.length - 1] = (n1 >>> 24) & 0xff; - - this.update(pad.buffer); - - const hash = new ArrayBuffer(16); - const hashView = new DataView(hash); - hashView.setUint32(0, this.#a, true); - hashView.setUint32(4, this.#b, true); - hashView.setUint32(8, this.#c, true); - hashView.setUint32(12, this.#d, true); - - return hash; - } - - /** - * Returns hash as a string of given format - * @param format format of output string (hex or base64). Default is hex - */ - toString(format: "hex" | "base64" = "hex"): string { - const hash = this.digest(); - - switch (format) { - case "hex": - return new TextDecoder().decode(hex.encode(new Uint8Array(hash))); - case "base64": { - const data = new Uint8Array(hash); - let dataString = ""; - for (let i = 0; i < data.length; ++i) { - dataString += String.fromCharCode(data[i]); - } - return btoa(dataString); - } - default: - throw new Error("md5: invalid format"); - } - } -}