Skip to content

Commit

Permalink
improve base94 encode decode responses
Browse files Browse the repository at this point in the history
  • Loading branch information
ivanjoz committed Jun 7, 2024
1 parent f3964cf commit fd0e07d
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 22 deletions.
9 changes: 7 additions & 2 deletions backend/core/helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -1371,7 +1371,7 @@ func ConcatInt64(num1, num2 int64) int64 {
}

// Base94 encoding takes 9 input bytes of 8 bits each, uses those to construct a 72-bit integer, and then converts that to an 11-digit base-94 number, and encodes that number using the ASCII characters ! (33) through ~ (126):
func Base94Encode(data []byte) string {
func Base94EncodeBytes(data []byte) []byte {
var encodeChunk = func(chunk []byte) string {
// Convert the 9-byte chunk to a 72-bit integer
var value big.Int
Expand Down Expand Up @@ -1414,7 +1414,12 @@ func Base94Encode(data []byte) string {
encoded.WriteString(encodeChunk(padded))
}

return fmt.Sprint(padding) + encoded.String()
paddingChar := fmt.Sprint(padding)
return append([]byte(paddingChar), encoded.Bytes()...)
}

func Base94Encode(data []byte) string {
return string(Base94EncodeBytes(data))
}

func Base94Decode(encoded string) ([]byte, error) {
Expand Down
13 changes: 7 additions & 6 deletions backend/core/responses.go
Original file line number Diff line number Diff line change
Expand Up @@ -647,16 +647,17 @@ func (req *HandlerArgs) MakeResponse(respStruct any) HandlerResponse {
if err := gz.Close(); err != nil {
log.Fatal(err)
}
bodyBytes = nil
bodyBytesCompressed := bodyCompressed.Bytes()
Log("Body bytes a enviar::", len(bodyBytesCompressed))
// Convert to base64 string because AWS WebSocket API Gateway does not support binary messages
base94message := Base94EncodeBytes(bodyBytesCompressed)
bodyBytesCompressed = nil
Log("Body bytes a enviar::", len(base94message))

if req.WebSocketConn != nil {
req.WebSocketConn.WriteMessage(websocket.BinaryMessage, bodyBytesCompressed)
req.WebSocketConn.WriteMessage(websocket.TextMessage, base94message)
} else if len(req.ConnectionID) > 0 {
// Convert to base64 because AWS WebSocket API Gateway does not support binary messages
bodyBase64Bytes := []byte{}
base64.StdEncoding.Encode(bodyBase64Bytes, bodyBytesCompressed)
SendWebsocketMessage(req.ConnectionID, &bodyBase64Bytes)
SendWebsocketMessage(req.ConnectionID, &base94message)
} else {
panic("No se pudo enviar el mensaje (Sin ConnID ni Conn)")
}
Expand Down
31 changes: 19 additions & 12 deletions frontend/src/core/halpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,11 +47,13 @@ export const base94Encode = (data: Uint8Array): string => {
return String(paddingSize) + encoded;
}

export const Base94Decode = (encoded: string): Uint8Array => {
const paddingSize = parseInt(encoded[0]);
encoded = encoded.slice(1);
const encodedChunkSize = 11;
const chunkSize = 9;
export const base94Decode = (encoded: string): Uint8Array => {
const paddingSize = parseInt(encoded[0])
encoded = encoded.slice(1)
const encodedChunkSize = 11
const chunkSize = 9
// const binarySize = ((encoded.length / encodedChunkSize) * 9) - paddingSize
// console.log("expected binarySize::", binarySize)

const decodeChunk = (chunk: string) => {
const asciiOffset = 33;
Expand All @@ -63,12 +65,12 @@ export const Base94Decode = (encoded: string): Uint8Array => {
// Convert the base94 string to a 72-bit integer
let value = BigInt(0);
for (let i = 0; i < chunk.length; i++) {
let char = BigInt(chunk.charCodeAt(i) - asciiOffset);
const char = BigInt(chunk.charCodeAt(i) - asciiOffset);
value = value * BigInt(94) + char;
}

// Convert the 72-bit integer to a 9-byte chunk
let decoded = [];
const decoded = [];
for (let i = chunkSize - 1; i >= 0; i--) {
decoded[i] = Number(value & BigInt(0xff));
value >>= BigInt(8);
Expand All @@ -81,15 +83,20 @@ export const Base94Decode = (encoded: string): Uint8Array => {
throw new Error(`Encoded string length must be a multiple of ${encodedChunkSize}`);
}

let decoded = [];
const decoded: number[] = [];

for (let i = 0; i < encoded.length; i += encodedChunkSize) {
let chunk = encoded.slice(i, i + encodedChunkSize);
let decodedChunk = decodeChunk(chunk);
const chunk = encoded.slice(i, i + encodedChunkSize);
let decodedChunk = decodeChunk(chunk);
if(paddingSize && i === (encoded.length - encodedChunkSize)){
decodedChunk = decodedChunk.slice(0, 9 - paddingSize)
}
decoded.push(...decodedChunk);
}

return new Uint8Array(decoded);
const binaryDecoded = new Uint8Array(decoded)
// console.log("final binarySize::", binaryDecoded.length)
return binaryDecoded
}

export const testBase94encode = () => {
Expand All @@ -100,7 +107,7 @@ export const testBase94encode = () => {
const data = encoder.encode(dataString)
const encoded = base94Encode(data)
console.log("encoded:", encoded)
const decoded = Base94Decode(encoded)
const decoded = base94Decode(encoded)
const decoder = new TextDecoder()
const decodedString = decoder.decode(decoded)
console.log("decoded:", decodedString)
Expand Down
9 changes: 7 additions & 2 deletions frontend/src/services/connection.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import Dexie from 'dexie'
import { createSignal } from 'solid-js'
import { GetWssAPI } from '~/app'
import { base94Encode } from '~/core/halpers'
import { base94Decode, base94Encode } from '~/core/halpers'

let dexieInitPromise: Promise<void>
let dexiedb: Dexie
Expand Down Expand Up @@ -169,9 +169,14 @@ export class ConnectionManager {
})

this.ws.onmessage = (event) => {
const blob = event.data
const base94gzString = event.data
console.log("bytes recibidos por decodificar::", base94gzString.length)
const base94gzArray = base94Decode(base94gzString)
console.log("bytes recibidos decodificados::", base94gzArray.length)
const blob = new Blob([base94gzArray], { type: 'application/gzip' })
const ds = new DecompressionStream('gzip');
const decompressedStream = blob.stream().pipeThrough(ds);

new Response(decompressedStream).blob().then((blob) => {
return blob.text()
}).then((responseText) => {
Expand Down

0 comments on commit fd0e07d

Please sign in to comment.