Refactoring
This commit is contained in:
@@ -8,12 +8,42 @@ export {
|
||||
};
|
||||
|
||||
export const base64ToBytes = (base64: string): Uint8Array => {
|
||||
const binaryString = atob(base64);
|
||||
const bytes = new Uint8Array(binaryString.length);
|
||||
for (let i = 0; i < binaryString.length; i++) {
|
||||
bytes[i] = binaryString.charCodeAt(i);
|
||||
// Normalize URL-safe base64 to standard base64
|
||||
let normalized = base64.replace(/-/g, '+').replace(/_/g, '/');
|
||||
// Add padding if missing
|
||||
while (normalized.length % 4 !== 0) {
|
||||
normalized += '=';
|
||||
}
|
||||
const binaryString = atob(normalized);
|
||||
const bytes = new Uint8Array(binaryString.length);
|
||||
for (let i = 0; i < binaryString.length; i++) {
|
||||
bytes[i] = binaryString.charCodeAt(i);
|
||||
}
|
||||
return bytes;
|
||||
}
|
||||
|
||||
export const encodedStringToBytes = (str: string, size: number): Uint8Array => {
|
||||
const hexRegex = /^[0-9a-fA-F]+$/;
|
||||
// Accept both standard and URL-safe base64, with or without padding
|
||||
const b64Regex = /^(?:[A-Za-z0-9+\/_-]{4})*(?:[A-Za-z0-9+\/_-]{2}(?:==)?|[A-Za-z0-9+\/_-]{3}=?)?$/;
|
||||
|
||||
if (hexRegex.test(str) && str.length === size * 2) {
|
||||
return hexToBytes(str);
|
||||
} else if (b64Regex.test(str)) {
|
||||
const bytes = base64ToBytes(str);
|
||||
if (bytes.length === size) {
|
||||
return bytes;
|
||||
}
|
||||
} else if (str.length === size) {
|
||||
// Raw format: treat as bytes (latin1)
|
||||
const bytes = new Uint8Array(size);
|
||||
for (let i = 0; i < size; i++) {
|
||||
bytes[i] = str.charCodeAt(i) & 0xFF;
|
||||
}
|
||||
return bytes;
|
||||
}
|
||||
|
||||
throw new Error(`Invalid input: expected hex, base64 (standard or URL-safe), or raw string of size ${size}`);
|
||||
}
|
||||
|
||||
export class BufferReader {
|
||||
@@ -79,3 +109,45 @@ export class BufferReader {
|
||||
return new Date(timestamp * 1000);
|
||||
}
|
||||
}
|
||||
|
||||
export class BufferWriter {
|
||||
private buffer: number[] = [];
|
||||
|
||||
public writeByte(value: number): void {
|
||||
this.buffer.push(value & 0xFF);
|
||||
}
|
||||
|
||||
public writeBytes(bytes: Uint8Array): void {
|
||||
this.buffer.push(...bytes);
|
||||
}
|
||||
|
||||
public writeUint16LE(value: number): void {
|
||||
this.buffer.push(value & 0xFF, (value >> 8) & 0xFF);
|
||||
}
|
||||
|
||||
public writeUint32LE(value: number): void {
|
||||
this.buffer.push(
|
||||
value & 0xFF,
|
||||
(value >> 8) & 0xFF,
|
||||
(value >> 16) & 0xFF,
|
||||
(value >> 24) & 0xFF
|
||||
);
|
||||
}
|
||||
|
||||
public writeInt16LE(value: number): void {
|
||||
this.writeUint16LE(value < 0 ? value + 0x10000 : value);
|
||||
}
|
||||
|
||||
public writeInt32LE(value: number): void {
|
||||
this.writeUint32LE(value < 0 ? value + 0x100000000 : value);
|
||||
}
|
||||
|
||||
public writeTimestamp(date: Date): void {
|
||||
const timestamp = Math.floor(date.getTime() / 1000);
|
||||
this.writeUint32LE(timestamp);
|
||||
}
|
||||
|
||||
public toBytes(): Uint8Array {
|
||||
return new Uint8Array(this.buffer);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user