0
# Format Support
1
2
Comprehensive support for hexadecimal and Base64 input formats, including PEM armoring and various encoding standards.
3
4
## Capabilities
5
6
### Hexadecimal Decoding
7
8
Decode hexadecimal strings and arrays into binary data with flexible whitespace handling.
9
10
```javascript { .api }
11
class Hex {
12
/**
13
* Decode hexadecimal string or array into binary data
14
* @param a - Hexadecimal string or array of character codes representing hex data
15
* @returns Uint8Array (when available) or regular array of bytes
16
* @throws Error if hex encoding is invalid or incomplete
17
*/
18
static decode(a: string | ArrayLike<number>): Uint8Array | number[];
19
}
20
```
21
22
**Usage Examples:**
23
24
```javascript
25
import { Hex } from '@lapo/asn1js/hex.js';
26
27
// Basic hex decoding
28
const hexString = "48656C6C6F20576F726C64";
29
const bytes = Hex.decode(hexString);
30
console.log(bytes); // [72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100]
31
32
// Lowercase hex
33
const lowerHex = "deadbeef";
34
const decoded = Hex.decode(lowerHex);
35
console.log(decoded); // [222, 173, 190, 239]
36
37
// Hex with whitespace (automatically ignored)
38
const spacedHex = "30 0C 06 03 2B 65 70 05 00";
39
const result = Hex.decode(spacedHex);
40
console.log(result); // [48, 12, 6, 3, 43, 101, 112, 5, 0]
41
42
// Hex with various whitespace characters (tabs, newlines, etc.)
43
const formattedHex = `30 0C 06 03
44
\t2B 65 70 05
45
\u00A000`;
46
const cleanResult = Hex.decode(formattedHex);
47
48
// From array of character codes
49
const charCodes = [52, 56, 54, 53, 54, 67]; // "48656C"
50
const fromArray = Hex.decode(charCodes);
51
console.log(fromArray); // [72, 101, 108]
52
```
53
54
### Base64 Decoding
55
56
Comprehensive Base64 decoding with support for standard Base64, Base64url, and PEM armoring.
57
58
```javascript { .api }
59
class Base64 {
60
/**
61
* Decode base64 string or array into binary data
62
* Supports both standard Base64 and Base64url (RFC 4648)
63
* @param a - Base64 string or array of character codes
64
* @returns Uint8Array (when available) or regular array of bytes
65
* @throws Error if base64 encoding is invalid
66
*/
67
static decode(a: string | ArrayLike<number>): Uint8Array | number[];
68
69
/**
70
* Format base64 string with proper padding and line breaks
71
* Converts Base64url to standard Base64 and adds proper formatting
72
* @param str - Base64 string to format
73
* @returns Formatted base64 string with padding and 80-column line breaks
74
*/
75
static pretty(str: string): string;
76
77
/**
78
* Extract and decode base64 from PEM or other armored formats
79
* Automatically detects and handles:
80
* - PEM format (-----BEGIN...-----END-----)
81
* - begin-base64...==== format
82
* - Raw base64 strings
83
* @param a - Armored or raw base64 string
84
* @returns Decoded binary data
85
* @throws Error if no valid base64 content found
86
*/
87
static unarmor(a: string): Uint8Array | number[];
88
89
/** Regular expression for detecting armored base64 content */
90
static re: RegExp;
91
}
92
```
93
94
**Usage Examples:**
95
96
```javascript
97
import { Base64 } from '@lapo/asn1js/base64.js';
98
99
// Basic base64 decoding
100
const base64String = "SGVsbG8gV29ybGQ=";
101
const bytes = Base64.decode(base64String);
102
console.log(bytes); // [72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100]
103
104
// Base64url decoding (automatically handled)
105
const base64url = "SGVsbG8gV29ybGQ"; // No padding
106
const urlDecoded = Base64.decode(base64url);
107
108
// Decode with whitespace (automatically ignored)
109
const spacedBase64 = `SGVs
110
bG8g
111
V29y
112
bGQ=`;
113
const spacedResult = Base64.decode(spacedBase64);
114
115
// PEM format decoding
116
const pemCert = `-----BEGIN CERTIFICATE-----
117
MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAxomBdI7QQ9PbTFKnRkTG
118
6LMU1Z4YuYcU5xDiIwz8sIBH2Z3f3X3bR0lPb0ZsU4U6z7z8z8z8z8z8z8z8z8z8
119
-----END CERTIFICATE-----`;
120
const certData = Base64.unarmor(pemCert);
121
122
// begin-base64 format
123
const beginBase64 = `begin-base64 644 certificate.der
124
MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAxomBdI7QQ9PbTFKnRkTG
125
====`;
126
const beginData = Base64.unarmor(beginBase64);
127
128
// Raw base64 (also works with unarmor)
129
const rawBase64 = "MIICIjANBgkqhkiG9w0BAQEFAAOCAg8A";
130
const rawData = Base64.unarmor(rawBase64);
131
132
// Format base64 for display
133
const longBase64 = "MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAxomBdI7QQ9PbTFKnRkTG6LMU1Z4YuYcU5xDiIwz8sIBH2Z3f3X3bR0lPb0ZsU4U6z7z8z8z8z8z8z8z8z8z8";
134
const formatted = Base64.pretty(longBase64);
135
console.log(formatted);
136
// Output: 80-character lines with proper padding
137
138
// Check what format a string uses
139
if (Base64.re.test(pemCert)) {
140
console.log("Contains armored base64");
141
}
142
```
143
144
### Combined Usage
145
146
Examples showing how to use format support with ASN.1 parsing.
147
148
```javascript
149
import { ASN1 } from '@lapo/asn1js';
150
import { Hex } from '@lapo/asn1js/hex.js';
151
import { Base64 } from '@lapo/asn1js/base64.js';
152
153
// Parse from various input formats
154
function parseASN1FromAnyFormat(input) {
155
let binaryData;
156
157
// Try to determine format and decode accordingly
158
if (typeof input === 'string') {
159
if (/^[0-9A-Fa-f\s]+$/.test(input)) {
160
// Looks like hex
161
binaryData = Hex.decode(input);
162
} else if (Base64.re.test(input) || /^[A-Za-z0-9+/=\s]+$/.test(input)) {
163
// Looks like base64 or PEM
164
binaryData = Base64.unarmor(input);
165
} else {
166
throw new Error('Unknown input format');
167
}
168
} else {
169
// Assume binary array
170
binaryData = input;
171
}
172
173
return ASN1.decode(binaryData);
174
}
175
176
// Examples of different input formats
177
const hexInput = "30 0C 06 03 2B 65 70 05 00";
178
const base64Input = "MAwGAytlcAUA";
179
const pemInput = `-----BEGIN PUBLIC KEY-----
180
MAwGAytlcAUA
181
-----END PUBLIC KEY-----`;
182
183
// All parse to the same ASN.1 structure
184
const fromHex = parseASN1FromAnyFormat(hexInput);
185
const fromBase64 = parseASN1FromAnyFormat(base64Input);
186
const fromPem = parseASN1FromAnyFormat(pemInput);
187
188
console.log(fromHex.toPrettyString());
189
console.log(fromBase64.toPrettyString());
190
console.log(fromPem.toPrettyString());
191
192
// Convert between formats
193
const asn1 = ASN1.decode(Hex.decode("300C06032B6570050000"));
194
const asHex = asn1.toHexString();
195
const asBase64 = asn1.toB64String();
196
const asBase64Std = asn1.toB64String('std');
197
198
console.log("Hex:", asHex);
199
console.log("Base64url:", asBase64);
200
console.log("Base64 standard:", asBase64Std);
201
202
// Create PEM-like output
203
const pemLike = `-----BEGIN ASN1 STRUCTURE-----
204
${Base64.pretty(asBase64Std)}
205
-----END ASN1 STRUCTURE-----`;
206
console.log(pemLike);
207
```
208
209
### Error Handling
210
211
The format support classes provide detailed error information for invalid input.
212
213
```javascript
214
import { Hex } from '@lapo/asn1js/hex.js';
215
import { Base64 } from '@lapo/asn1js/base64.js';
216
217
// Hex error examples
218
try {
219
Hex.decode("48656C6C6F2"); // Incomplete hex (odd number of characters)
220
} catch (e) {
221
console.log(e.message); // "Hex encoding incomplete: 4 bits missing"
222
}
223
224
try {
225
Hex.decode("48656C6G"); // Invalid hex character 'G'
226
} catch (e) {
227
console.log(e.message); // "Illegal character at offset 6"
228
}
229
230
// Base64 error examples
231
try {
232
Base64.decode("SGVsbG8g!"); // Invalid base64 character '!'
233
} catch (e) {
234
console.log(e.message); // "Illegal character at offset 8"
235
}
236
237
try {
238
Base64.decode("SGVsbG8"); // Incomplete base64
239
} catch (e) {
240
console.log(e.message); // "Base64 encoding incomplete: at least 2 bits missing"
241
}
242
243
// PEM error examples
244
try {
245
Base64.unarmor("-----BEGIN CERTIFICATE-----\nInvalid content\n-----END CERTIFICATE-----");
246
} catch (e) {
247
console.log(e.message); // Base64 decoding error
248
}
249
```