diff --git a/src/decrypt-worker/crypto/qmc/qmc_v2.ts b/src/decrypt-worker/crypto/qmc/qmc_v2.ts index 116a2a8..c39234a 100644 --- a/src/decrypt-worker/crypto/qmc/qmc_v2.ts +++ b/src/decrypt-worker/crypto/qmc/qmc_v2.ts @@ -3,6 +3,7 @@ import type { CryptoBase } from '../CryptoBase'; import type { DecryptCommandOptions } from '~/decrypt-worker/types.ts'; import { SEED, ENC_V2_KEY_1, ENC_V2_KEY_2 } from './qmc_v2.key.ts'; import { fetchParakeet } from '@jixun/libparakeet'; +import { stringToUTF8Bytes } from '~/decrypt-worker/util/utf8Encoder.ts'; export class QMC2Crypto implements CryptoBase { cryptoName = 'QMC/v2'; @@ -36,8 +37,7 @@ export class QMC2CryptoWithKey implements CryptoBase { } const parakeet = await fetchParakeet(); - const textEncoder = new TextEncoder(); - const key = textEncoder.encode(options.qmc2Key); + const key = stringToUTF8Bytes(options.qmc2Key); const keyCrypto = parakeet.make.QMCv2KeyCrypto(SEED, ENC_V2_KEY_1, ENC_V2_KEY_2); return transformBlob(buffer, (p) => p.make.QMCv2EKey(key, keyCrypto), { parakeet, diff --git a/src/decrypt-worker/util/utf8Encoder.ts b/src/decrypt-worker/util/utf8Encoder.ts new file mode 100644 index 0000000..e679be2 --- /dev/null +++ b/src/decrypt-worker/util/utf8Encoder.ts @@ -0,0 +1,10 @@ +export const utf8Encoder = new TextEncoder(); +export const utf8Decoder = new TextDecoder('utf-8'); + +export function stringToUTF8Bytes(str: string) { + return utf8Encoder.encode(str); +} + +export function bytesToUTF8String(str: BufferSource) { + return utf8Decoder.decode(str); +} diff --git a/src/util/MMKVParser.ts b/src/util/MMKVParser.ts index 943e07a..f2a7d43 100644 --- a/src/util/MMKVParser.ts +++ b/src/util/MMKVParser.ts @@ -1,8 +1,7 @@ import type { StagingKWMv2Key } from '~/features/settings/keyFormats'; +import { bytesToUTF8String } from '~/decrypt-worker/util/utf8Encoder'; import { formatHex } from './formatHex'; -const textDecoder = new TextDecoder('utf-8', { ignoreBOM: true }); - export class MMKVParser { private offset = 4; private length: number; @@ -67,7 +66,7 @@ export class MMKVParser { // ] const strByteLen = this.readInt(); const data = this.readBytes(strByteLen); - return textDecoder.decode(data).normalize(); + return bytesToUTF8String(data).normalize(); } public readVariantString() { diff --git a/src/util/levenshtein.ts b/src/util/levenshtein.ts index 49617c5..340a057 100644 --- a/src/util/levenshtein.ts +++ b/src/util/levenshtein.ts @@ -1,6 +1,6 @@ -const textEncoder = new TextEncoder(); - // translation of pseudocode from Wikipedia: +import { stringToUTF8Bytes } from '~/decrypt-worker/util/utf8Encoder'; + // https://en.wikipedia.org/wiki/Levenshtein_distance#Iterative_with_two_matrix_rows export function levenshtein(str1: string, str2: string) { if (str1 === str2) { @@ -14,8 +14,8 @@ export function levenshtein(str1: string, str2: string) { } // Convert them to Uint8Array to avoid expensive string APIs. - const s = textEncoder.encode(str1.toLowerCase()); - const t = textEncoder.encode(str2.toLowerCase()); + const s = stringToUTF8Bytes(str1.normalize().toLowerCase()); + const t = stringToUTF8Bytes(str2.normalize().toLowerCase()); const m = s.byteLength; const n = t.byteLength;