# crypto — Encoding Conversion and JWT > `import { encoder, jwtDecode } from 'puffy-core/crypto'` > CJS: `const { crypto: { encoder, jwtDecode } } = require('puffy-core')` > Also available in snake_case: `jwt_decode` --- ## encoder Curried encoding converter with **3 stages**: `encoder(fromEncoding)(toEncoding)(data)`. ### Signature ``` encoder(fromEncoding?: string) → (toEncoding?: string) → (data: string|Buffer) → string|number|Buffer ``` Supported encodings: `'utf8'` (default when omitted), `'base64'`, `'hex'`, `'bin'`, `'buffer'`, `'int'`, `'ascii'` ### How the 3 stages work ``` Stage 1: encoder(from) → returns a function that knows the source encoding Stage 2: (to) → returns a function that knows both source and target Stage 3: (data) → performs the conversion and returns the result ``` You can store any stage for reuse: ```js // Store at stage 2 — reusable converter const stringToBase64 = encoder()('base64') // utf8 → base64 const base64ToString = encoder('base64')() // base64 → utf8 // Use at stage 3 stringToBase64('hello world') // 'aGVsbG8gd29ybGQ=' base64ToString('aGVsbG8gd29ybGQ=') // 'hello world' ``` ### Example — All common conversion patterns ```js // utf8 (default) to other encodings const stringToBase64 = encoder()('base64') const stringToHex = encoder()('hex') const stringToBin = encoder()('bin') const stringToBuffer = encoder()('buffer') stringToBase64('hello world') // 'aGVsbG8gd29ybGQ=' stringToHex('hello world') // '68656C6C6F20776F726C64' stringToBin('hello world') // '0110100001100101011011000110110001101111001000000111011101101111011100100110110001100100' stringToBuffer('hello world') // // base64 to other encodings const base64ToString = encoder('base64')() const base64ToHex = encoder('base64')('hex') const base64ToBin = encoder('base64')('bin') const base64ToBuffer = encoder('base64')('buffer') base64ToString('aGVsbG8gd29ybGQ=') // 'hello world' base64ToHex('aGVsbG8gd29ybGQ=') // '68656C6C6F20776F726C64' // hex to other encodings const hexToString = encoder('hex')() const hexToBase64 = encoder('hex')('base64') const hexToBin = encoder('hex')('bin') const hexToBuffer = encoder('hex')('buffer') hexToString('68656C6C6F20776F726C64') // 'hello world' hexToBase64('68656C6C6F20776F726C64') // 'aGVsbG8gd29ybGQ=' // bin (binary string) to other encodings const binToString = encoder('bin')() const binToBase64 = encoder('bin')('base64') const binToHex = encoder('bin')('hex') binToString('0110100001100101011011000110110001101111001000000111011101101111011100100110110001100100') // 'hello world' // buffer to other encodings const bufferToString = encoder('buffer')() const bufferToBase64 = encoder('buffer')('base64') const bufferToHex = encoder('buffer')('hex') const bufferToBin = encoder('buffer')('bin') ``` ### Example — One-liner (all 3 stages in one call) ```js encoder()('base64')('hello world') // 'aGVsbG8gd29ybGQ=' encoder('base64')()('aGVsbG8gd29ybGQ=') // 'hello world' encoder('base64')('hex')('aGVsbG8gd29ybGQ=') // '68656C6C6F20776F726C64' encoder()('hex')('hello world') // '68656C6C6F20776F726C64' encoder('hex')('bin')('AF') // '10101111' ``` ### Return types by target encoding | Target encoding | Return type | Example output | |---|---|---| | `'utf8'` (or omitted) | string | `'hello world'` | | `'ascii'` | string | `'hello world'` | | `'base64'` | string | `'aGVsbG8gd29ybGQ='` | | `'hex'` | string (UPPERCASE) | `'68656C6C6F20776F726C64'` | | `'bin'` | string (0s and 1s) | `'011010000110...'` | | `'int'` | number | `175` | | `'buffer'` | Buffer (Node.js only) | `` | ### GOTCHA: Missing a stage returns a function, not a value ```js // WRONG — only 2 stages, returns a function const oops = encoder('base64')('hello world') // oops is a FUNCTION (stage 2 received 'hello world' as toEncoding) // CORRECT — all 3 stages const result = encoder('base64')()('aGVsbG8gd29ybGQ=') // result = 'hello world' ``` GOTCHA: `'buffer'` encoding only works in Node.js. In browser environments, use `'base64'` or `'hex'` instead. GOTCHA: `'int'` is only useful as a target encoding (output). It converts hex to a decimal number. --- ## jwtDecode Decodes a JWT token without verifying the signature. Useful for reading claims from tokens. ### Signature ``` jwtDecode(token: string, options?: { noFail?: boolean }) → Object|null ``` Parameters: - `token`: JWT string (three dot-separated base64 segments) - `options.noFail`: If `true`, returns `null` on invalid tokens instead of throwing Returns: ```js { header: { alg: string, kid: string, ... }, payload: { sub: string, iss: string, exp: number, iat: number, ... }, signBase64: string // raw base64 signature } ``` ### Example ```js const { header, payload, signBase64 } = jwtDecode(myToken) console.log(payload.sub) // user ID console.log(payload.exp) // expiry timestamp (epoch seconds) // Check if expired: const isExpired = payload.exp < Date.now() / 1000 // Safe decoding (returns null on invalid token): const result = jwtDecode('not-a-valid-token', { noFail: true }) // result = null (no exception thrown) // Without noFail, invalid tokens throw: jwtDecode('not-a-valid-token') // throws Error ``` GOTCHA: This does NOT verify the JWT signature. Do not use this for authentication decisions — only for reading claims from already-trusted tokens.