CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-sjcl

Stanford JavaScript Crypto Library providing comprehensive cryptographic operations including AES encryption, hash functions, key derivation, and elliptic curve cryptography.

Pending
Overview
Eval results
Files

data-encoding.mddocs/

Data Encoding

SJCL provides comprehensive encoding and decoding capabilities for converting between bit arrays and various string formats including UTF-8, Base64, hexadecimal, Base32, and binary formats.

Capabilities

UTF-8 String Encoding

Convert between UTF-8 strings and SJCL's internal bit array format.

/**
 * Convert UTF-8 string to bit array
 * @param {string} str - UTF-8 string to convert
 * @returns {BitArray} String data as bit array
 */
sjcl.codec.utf8String.toBits(str);

/**
 * Convert bit array to UTF-8 string
 * @param {BitArray} arr - Bit array to convert
 * @returns {string} UTF-8 encoded string
 */
sjcl.codec.utf8String.fromBits(arr);

Usage Examples:

const sjcl = require('sjcl');

// String to bit array conversion
const text = "Hello, 世界! 🌍";
const bits = sjcl.codec.utf8String.toBits(text);
console.log("Bits:", bits); // Array of 32-bit integers

// Bit array back to string
const decoded = sjcl.codec.utf8String.fromBits(bits);
console.log("Decoded:", decoded); // "Hello, 世界! 🌍"

// Use with encryption
const key = sjcl.random.randomWords(8);
const plaintext = sjcl.codec.utf8String.toBits("Secret message");
const encrypted = sjcl.encrypt("password", sjcl.codec.utf8String.fromBits(plaintext));

Hexadecimal Encoding

Convert between hexadecimal strings and bit arrays for readable binary data representation.

/**
 * Convert hexadecimal string to bit array
 * @param {string} str - Hexadecimal string (case insensitive, spaces/0x ignored)
 * @returns {BitArray} Binary data as bit array
 */
sjcl.codec.hex.toBits(str);

/**
 * Convert bit array to hexadecimal string
 * @param {BitArray} arr - Bit array to convert
 * @returns {string} Lowercase hexadecimal string
 */
sjcl.codec.hex.fromBits(arr);

Usage Examples:

const sjcl = require('sjcl');

// Hex string to bit array
const hexString = "deadbeef";
const hexBits = sjcl.codec.hex.toBits(hexString);
console.log("Hex bits:", hexBits);

// Bit array to hex string
const hexDecoded = sjcl.codec.hex.fromBits(hexBits);
console.log("Hex decoded:", hexDecoded); // "deadbeef"

// Hash to hex example
const hash = sjcl.hash.sha256.hash("Hello, World!");
const hexHash = sjcl.codec.hex.fromBits(hash);
console.log("SHA-256 hex:", hexHash);

// Flexible hex input (spaces, 0x prefix, mixed case)
const flexHex = sjcl.codec.hex.toBits("0xDEAD BEEF cafe");
console.log("Flexible hex:", sjcl.codec.hex.fromBits(flexHex));

Base64 Encoding

Standard Base64 encoding for binary data transmission and storage.

/**
 * Convert bit array to Base64 string
 * @param {BitArray} arr - Bit array to encode
 * @param {boolean} [_noEquals] - Omit padding equals signs
 * @param {boolean} [_url] - Use URL-safe Base64 alphabet
 * @returns {string} Base64 encoded string
 */
sjcl.codec.base64.fromBits(arr, _noEquals, _url);

/**
 * Convert Base64 string to bit array
 * @param {string} str - Base64 string to decode
 * @param {boolean} [_url] - Use URL-safe Base64 alphabet
 * @returns {BitArray} Decoded binary data as bit array
 * @throws {sjcl.exception.invalid} If Base64 string is invalid
 */
sjcl.codec.base64.toBits(str, _url);

Usage Examples:

const sjcl = require('sjcl');

// Basic Base64 encoding
const data = sjcl.codec.utf8String.toBits("Hello, World!");
const base64 = sjcl.codec.base64.fromBits(data);
console.log("Base64:", base64); // "SGVsbG8sIFdvcmxkIQ=="

// Base64 decoding
const decoded = sjcl.codec.base64.toBits(base64);
const text = sjcl.codec.utf8String.fromBits(decoded);
console.log("Decoded:", text); // "Hello, World!"

// Base64 without padding
const noPadding = sjcl.codec.base64.fromBits(data, true);
console.log("No padding:", noPadding); // "SGVsbG8sIFdvcmxkIQ"

// URL-safe Base64
const urlSafe = sjcl.codec.base64.fromBits(data, false, true);
console.log("URL-safe:", urlSafe); // Uses - and _ instead of + and /

Base64URL Encoding

URL and filename safe Base64 encoding variant.

/**
 * Convert bit array to Base64URL string
 * @param {BitArray} arr - Bit array to encode
 * @returns {string} Base64URL encoded string (no padding)
 */
sjcl.codec.base64url.fromBits(arr);

/**
 * Convert Base64URL string to bit array
 * @param {string} str - Base64URL string to decode
 * @returns {BitArray} Decoded binary data as bit array
 */
sjcl.codec.base64url.toBits(str);

Usage Examples:

const sjcl = require('sjcl');

// Base64URL encoding (commonly used in JWT tokens)
const payload = sjcl.codec.utf8String.toBits('{"sub":"1234567890","name":"John Doe"}');
const base64url = sjcl.codec.base64url.fromBits(payload);
console.log("Base64URL:", base64url); // URL-safe, no padding

// JWT-style usage
function createJWTPayload(data) {
  const payloadBits = sjcl.codec.utf8String.toBits(JSON.stringify(data));
  return sjcl.codec.base64url.fromBits(payloadBits);
}

const tokenPayload = createJWTPayload({
  sub: "user123",
  exp: Math.floor(Date.now() / 1000) + 3600
});

Base32 Encoding

Base32 encoding for use cases requiring case-insensitive alphanumeric encoding.

/**
 * Convert bit array to Base32 string
 * @param {BitArray} arr - Bit array to encode
 * @param {boolean} [_noEquals] - Omit padding equals signs
 * @param {boolean} [_hex] - Use Base32hex alphabet instead of standard
 * @returns {string} Base32 encoded string
 */
sjcl.codec.base32.fromBits(arr, _noEquals, _hex);

/**
 * Convert Base32 string to bit array
 * @param {string} str - Base32 string to decode (case insensitive)
 * @param {boolean} [_hex] - Use Base32hex alphabet instead of standard
 * @returns {BitArray} Decoded binary data as bit array
 * @throws {sjcl.exception.invalid} If Base32 string is invalid
 */
sjcl.codec.base32.toBits(str, _hex);

Base32Hex variant:

/**
 * Convert bit array to Base32hex string
 * @param {BitArray} arr - Bit array to encode
 * @param {boolean} [_noEquals] - Omit padding equals signs
 * @returns {string} Base32hex encoded string
 */
sjcl.codec.base32hex.fromBits(arr, _noEquals);

/**
 * Convert Base32hex string to bit array
 * @param {string} str - Base32hex string to decode
 * @returns {BitArray} Decoded binary data as bit array
 */
sjcl.codec.base32hex.toBits(str);

Usage Examples:

const sjcl = require('sjcl');

// Standard Base32 encoding
const data = sjcl.codec.utf8String.toBits("Hello, World!");
const base32 = sjcl.codec.base32.fromBits(data);
console.log("Base32:", base32); // "JBSWY3DPEBLW64TMMQQQ===="

// Base32 decoding (case insensitive)
const base32Lower = base32.toLowerCase();
const decoded = sjcl.codec.base32.toBits(base32Lower);
console.log("Decoded:", sjcl.codec.utf8String.fromBits(decoded));

// Base32hex (uses 0-9 and A-V instead of A-Z and 2-7)
const base32hex = sjcl.codec.base32hex.fromBits(data);
console.log("Base32hex:", base32hex);

// Without padding
const noPadding = sjcl.codec.base32.fromBits(data, true);
console.log("No padding:", noPadding);

Byte Array Encoding

Convert between bit arrays and regular JavaScript byte arrays.

/**
 * Convert bit array to byte array
 * @param {BitArray} arr - Bit array to convert
 * @returns {number[]} Array of bytes (0-255)
 */
sjcl.codec.bytes.fromBits(arr);

/**
 * Convert byte array to bit array
 * @param {number[]} bytes - Array of bytes (0-255)
 * @returns {BitArray} Bit array representation
 */
sjcl.codec.bytes.toBits(bytes);

Usage Examples:

const sjcl = require('sjcl');

// Bit array to byte array
const bits = sjcl.codec.utf8String.toBits("Hello!");
const bytes = sjcl.codec.bytes.fromBits(bits);
console.log("Bytes:", bytes); // [72, 101, 108, 108, 111, 33]

// Byte array to bit array
const backToBits = sjcl.codec.bytes.toBits(bytes);
const text = sjcl.codec.utf8String.fromBits(backToBits);
console.log("Back to text:", text); // "Hello!"

// Working with binary data
const binaryData = [0xFF, 0xFE, 0xFD, 0xFC];
const binaryBits = sjcl.codec.bytes.toBits(binaryData);
const hexView = sjcl.codec.hex.fromBits(binaryBits);
console.log("Hex view:", hexView); // "fffefdfc"

ArrayBuffer Encoding

Convert between bit arrays and ArrayBuffer objects for modern binary data handling.

/**
 * Convert bit array to ArrayBuffer
 * @param {BitArray} arr - Bit array to convert
 * @param {boolean} [padding] - Add padding if needed
 * @param {number} [padding_count] - Number of padding bytes
 * @returns {ArrayBuffer} ArrayBuffer containing binary data
 */
sjcl.codec.arrayBuffer.fromBits(arr, padding, padding_count);

/**
 * Convert ArrayBuffer to bit array
 * @param {ArrayBuffer} buffer - ArrayBuffer to convert
 * @returns {BitArray} Bit array representation
 */
sjcl.codec.arrayBuffer.toBits(buffer);

/**
 * Generate hex dump of ArrayBuffer contents
 * @param {ArrayBuffer} buffer - ArrayBuffer to dump
 * @returns {string} Hex dump string for debugging
 */
sjcl.codec.arrayBuffer.hexDumpBuffer(buffer);

Usage Examples:

const sjcl = require('sjcl');

// Bit array to ArrayBuffer
const bits = sjcl.codec.utf8String.toBits("Hello, ArrayBuffer!");
const buffer = sjcl.codec.arrayBuffer.fromBits(bits);
console.log("Buffer length:", buffer.byteLength);

// ArrayBuffer to bit array
const backToBits = sjcl.codec.arrayBuffer.toBits(buffer);
const text = sjcl.codec.utf8String.fromBits(backToBits);
console.log("Decoded:", text);

// Hex dump for debugging
const hexDump = sjcl.codec.arrayBuffer.hexDumpBuffer(buffer);
console.log("Hex dump:", hexDump);

// Working with TypedArrays
const uint8Array = new Uint8Array(buffer);
console.log("First bytes:", Array.from(uint8Array.slice(0, 5)));

Z85 Encoding

Z85 encoding (ZeroMQ Base85) for compact binary data representation.

/**
 * Convert bit array to Z85 string
 * @param {BitArray} arr - Bit array to encode (length must be multiple of 4 bytes)
 * @returns {string} Z85 encoded string
 * @throws {sjcl.exception.invalid} If data length is not multiple of 4 bytes
 */
sjcl.codec.z85.fromBits(arr);

/**
 * Convert Z85 string to bit array
 * @param {string} str - Z85 string to decode
 * @returns {BitArray} Decoded binary data as bit array
 * @throws {sjcl.exception.invalid} If Z85 string is invalid
 */
sjcl.codec.z85.toBits(str);

Usage Examples:

const sjcl = require('sjcl');

// Z85 encoding (data must be multiple of 4 bytes)
const data = sjcl.random.randomWords(2); // 8 bytes = 64 bits
const z85 = sjcl.codec.z85.fromBits(data);
console.log("Z85:", z85);

// Z85 decoding
const decoded = sjcl.codec.z85.toBits(z85);
console.log("Equal:", sjcl.bitArray.equal(data, decoded));

// Padding data to 4-byte boundary
function padToZ85(bits) {\n  const bitLength = sjcl.bitArray.bitLength(bits);\n  const byteLength = Math.ceil(bitLength / 8);\n  const paddedByteLength = Math.ceil(byteLength / 4) * 4;\n  const paddedBitLength = paddedByteLength * 8;\n  \n  return sjcl.bitArray.clamp(sjcl.bitArray.concat(bits, [0]), paddedBitLength);\n}\n\nconst text = sjcl.codec.utf8String.toBits(\"Hello\"); // 5 bytes\nconst padded = padToZ85(text);\nconst z85Text = sjcl.codec.z85.fromBits(padded);\n```\n\n## Common Encoding Patterns\n\n### Multi-format Conversion\n\nConvert data between multiple formats:\n\n```javascript\nconst sjcl = require('sjcl');\n\nfunction convertFormats(data, fromFormat, toFormat) {\n  let bits;\n  \n  // Convert from source format to bit array\n  switch (fromFormat) {\n    case 'utf8':\n      bits = sjcl.codec.utf8String.toBits(data);\n      break;\n    case 'hex':\n      bits = sjcl.codec.hex.toBits(data);\n      break;\n    case 'base64':\n      bits = sjcl.codec.base64.toBits(data);\n      break;\n    case 'base32':\n      bits = sjcl.codec.base32.toBits(data);\n      break;\n    default:\n      throw new Error('Unknown source format');\n  }\n  \n  // Convert from bit array to target format\n  switch (toFormat) {\n    case 'utf8':\n      return sjcl.codec.utf8String.fromBits(bits);\n    case 'hex':\n      return sjcl.codec.hex.fromBits(bits);\n    case 'base64':\n      return sjcl.codec.base64.fromBits(bits);\n    case 'base32':\n      return sjcl.codec.base32.fromBits(bits);\n    case 'bytes':\n      return sjcl.codec.bytes.fromBits(bits);\n    default:\n      throw new Error('Unknown target format');\n  }\n}\n\n// Usage\nconst hex = convertFormats(\"Hello, World!\", 'utf8', 'hex');\nconst base64 = convertFormats(hex, 'hex', 'base64');\nconst text = convertFormats(base64, 'base64', 'utf8');\nconsole.log(text); // \"Hello, World!\"\n```\n\n### Safe Encoding with Validation\n\nValidate and safely encode/decode data:\n\n```javascript\nconst sjcl = require('sjcl');\n\nclass SafeEncoder {\n  static encodeText(text, format = 'base64') {\n    if (typeof text !== 'string') {\n      throw new sjcl.exception.invalid('Input must be a string');\n    }\n    \n    const bits = sjcl.codec.utf8String.toBits(text);\n    \n    switch (format.toLowerCase()) {\n      case 'hex':\n        return sjcl.codec.hex.fromBits(bits);\n      case 'base64':\n        return sjcl.codec.base64.fromBits(bits);\n      case 'base32':\n        return sjcl.codec.base32.fromBits(bits);\n      default:\n        throw new sjcl.exception.invalid('Unsupported format');\n    }\n  }\n  \n  static decodeText(encoded, format = 'base64') {\n    try {\n      let bits;\n      \n      switch (format.toLowerCase()) {\n        case 'hex':\n          bits = sjcl.codec.hex.toBits(encoded);\n          break;\n        case 'base64':\n          bits = sjcl.codec.base64.toBits(encoded);\n          break;\n        case 'base32':\n          bits = sjcl.codec.base32.toBits(encoded);\n          break;\n        default:\n          throw new sjcl.exception.invalid('Unsupported format');\n      }\n      \n      return sjcl.codec.utf8String.fromBits(bits);\n    } catch (e) {\n      throw new sjcl.exception.corrupt('Invalid encoded data: ' + e.message);\n    }\n  }\n}\n\n// Usage\ntry {\n  const encoded = SafeEncoder.encodeText(\"Hello, World!\", 'base64');\n  const decoded = SafeEncoder.decodeText(encoded, 'base64');\n  console.log('Success:', decoded);\n} catch (e) {\n  console.error('Encoding error:', e.message);\n}\n```\n\n## Performance Considerations\n\n- **UTF-8**: Fastest for text data\n- **Hex**: Good for debugging and human-readable binary data\n- **Base64**: Standard for binary data transmission\n- **Base32**: Case-insensitive, good for user input\n- **Z85**: Most compact for binary data\n- **ArrayBuffer**: Best for modern JavaScript binary data handling\n\n## Security Considerations\n\n1. **Data Validation**: Always validate input before decoding\n2. **Error Handling**: Handle encoding/decoding errors gracefully\n3. **Memory**: Be aware of memory usage with large data\n4. **Timing**: Encoding/decoding operations are not constant-time\n5. **Character Sets**: Ensure proper UTF-8 handling for international text

Install with Tessl CLI

npx tessl i tessl/npm-sjcl

docs

big-number-arithmetic.md

bit-array-utilities.md

cipher-modes.md

data-encoding.md

elliptic-curve-cryptography.md

hash-functions.md

high-level-encryption.md

index.md

key-derivation.md

key-exchange.md

message-authentication.md

random-number-generation.md

symmetric-encryption.md

tile.json