@rog0x/mcp-crypto-tools 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +68 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +340 -0
- package/dist/tools/encode-decode.d.ts +40 -0
- package/dist/tools/encode-decode.js +141 -0
- package/dist/tools/hash.d.ts +19 -0
- package/dist/tools/hash.js +74 -0
- package/dist/tools/jwt-tools.d.ts +26 -0
- package/dist/tools/jwt-tools.js +135 -0
- package/dist/tools/password-tools.d.ts +28 -0
- package/dist/tools/password-tools.js +175 -0
- package/dist/tools/uuid-generator.d.ts +20 -0
- package/dist/tools/uuid-generator.js +109 -0
- package/package.json +19 -0
- package/src/index.ts +338 -0
- package/src/tools/encode-decode.ts +150 -0
- package/src/tools/hash.ts +88 -0
- package/src/tools/jwt-tools.ts +163 -0
- package/src/tools/password-tools.ts +191 -0
- package/src/tools/uuid-generator.ts +123 -0
- package/tsconfig.json +18 -0
package/README.md
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
# mcp-crypto-tools
|
|
2
|
+
|
|
3
|
+
Cryptography and encoding tools for AI agents, served via the [Model Context Protocol (MCP)](https://modelcontextprotocol.io).
|
|
4
|
+
|
|
5
|
+
## Tools
|
|
6
|
+
|
|
7
|
+
### hash
|
|
8
|
+
|
|
9
|
+
Hash text using MD5, SHA-1, SHA-256, SHA-512, or HMAC. Compare two hash values. Compute all algorithms at once.
|
|
10
|
+
|
|
11
|
+
**Actions:** `hash`, `hmac`, `compare`, `hash_all`
|
|
12
|
+
|
|
13
|
+
### encode_decode
|
|
14
|
+
|
|
15
|
+
Encode and decode text using Base64, URL encoding, HTML entities, hex, or binary. Auto-detect encoding format.
|
|
16
|
+
|
|
17
|
+
**Actions:** `base64_encode`, `base64_decode`, `url_encode`, `url_decode`, `html_encode`, `html_decode`, `hex_encode`, `hex_decode`, `binary_encode`, `binary_decode`, `detect`
|
|
18
|
+
|
|
19
|
+
### generate_id
|
|
20
|
+
|
|
21
|
+
Generate unique identifiers: UUID v4, nanoid, ULID, CUID, or random strings with configurable length and charset.
|
|
22
|
+
|
|
23
|
+
**Types:** `uuid`, `nanoid`, `ulid`, `cuid`, `random`
|
|
24
|
+
|
|
25
|
+
### password
|
|
26
|
+
|
|
27
|
+
Generate secure passwords with configurable character sets, length, and count. Check password strength with entropy calculation and crack time estimation.
|
|
28
|
+
|
|
29
|
+
**Actions:** `generate`, `check_strength`
|
|
30
|
+
|
|
31
|
+
### jwt
|
|
32
|
+
|
|
33
|
+
Decode JWT tokens to inspect header and payload, check expiry status, or create unsigned JWTs for testing.
|
|
34
|
+
|
|
35
|
+
**Actions:** `decode`, `check_expiry`, `create_unsigned`
|
|
36
|
+
|
|
37
|
+
## Setup
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
npm install
|
|
41
|
+
npm run build
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## MCP Configuration
|
|
45
|
+
|
|
46
|
+
Add to your MCP client configuration:
|
|
47
|
+
|
|
48
|
+
```json
|
|
49
|
+
{
|
|
50
|
+
"mcpServers": {
|
|
51
|
+
"crypto-tools": {
|
|
52
|
+
"command": "node",
|
|
53
|
+
"args": ["D:/products/mcp-servers/mcp-crypto-tools/dist/index.js"]
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
## Dependencies
|
|
60
|
+
|
|
61
|
+
- `@modelcontextprotocol/sdk` - MCP server framework
|
|
62
|
+
- Node.js built-in `crypto` module - all cryptographic operations
|
|
63
|
+
|
|
64
|
+
No external crypto libraries required.
|
|
65
|
+
|
|
66
|
+
## License
|
|
67
|
+
|
|
68
|
+
MIT
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1,340 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
const index_js_1 = require("@modelcontextprotocol/sdk/server/index.js");
|
|
5
|
+
const stdio_js_1 = require("@modelcontextprotocol/sdk/server/stdio.js");
|
|
6
|
+
const types_js_1 = require("@modelcontextprotocol/sdk/types.js");
|
|
7
|
+
const hash_js_1 = require("./tools/hash.js");
|
|
8
|
+
const encode_decode_js_1 = require("./tools/encode-decode.js");
|
|
9
|
+
const uuid_generator_js_1 = require("./tools/uuid-generator.js");
|
|
10
|
+
const password_tools_js_1 = require("./tools/password-tools.js");
|
|
11
|
+
const jwt_tools_js_1 = require("./tools/jwt-tools.js");
|
|
12
|
+
const server = new index_js_1.Server({
|
|
13
|
+
name: "mcp-crypto-tools",
|
|
14
|
+
version: "1.0.0",
|
|
15
|
+
}, {
|
|
16
|
+
capabilities: {
|
|
17
|
+
tools: {},
|
|
18
|
+
},
|
|
19
|
+
});
|
|
20
|
+
// List available tools
|
|
21
|
+
server.setRequestHandler(types_js_1.ListToolsRequestSchema, async () => ({
|
|
22
|
+
tools: [
|
|
23
|
+
{
|
|
24
|
+
name: "hash",
|
|
25
|
+
description: "Hash text using MD5, SHA-1, SHA-256, SHA-512, or HMAC. Can also compare two hash values or compute all hash algorithms at once.",
|
|
26
|
+
inputSchema: {
|
|
27
|
+
type: "object",
|
|
28
|
+
properties: {
|
|
29
|
+
action: {
|
|
30
|
+
type: "string",
|
|
31
|
+
enum: ["hash", "hmac", "compare", "hash_all"],
|
|
32
|
+
description: "Action to perform: hash (single algorithm), hmac (keyed hash), compare (compare two hashes), hash_all (all algorithms at once)",
|
|
33
|
+
},
|
|
34
|
+
text: { type: "string", description: "Text to hash (for hash, hmac, hash_all actions)" },
|
|
35
|
+
algorithm: {
|
|
36
|
+
type: "string",
|
|
37
|
+
enum: ["md5", "sha1", "sha256", "sha512"],
|
|
38
|
+
description: "Hash algorithm (for hash and hmac actions). Default: sha256",
|
|
39
|
+
},
|
|
40
|
+
key: { type: "string", description: "Secret key (for hmac action)" },
|
|
41
|
+
hash1: { type: "string", description: "First hash (for compare action)" },
|
|
42
|
+
hash2: { type: "string", description: "Second hash (for compare action)" },
|
|
43
|
+
encoding: {
|
|
44
|
+
type: "string",
|
|
45
|
+
enum: ["hex", "base64"],
|
|
46
|
+
description: "Output encoding. Default: hex",
|
|
47
|
+
},
|
|
48
|
+
},
|
|
49
|
+
required: ["action"],
|
|
50
|
+
},
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
name: "encode_decode",
|
|
54
|
+
description: "Encode or decode text using Base64, URL encoding, HTML entities, hex, or binary. Can also auto-detect the encoding format of input.",
|
|
55
|
+
inputSchema: {
|
|
56
|
+
type: "object",
|
|
57
|
+
properties: {
|
|
58
|
+
action: {
|
|
59
|
+
type: "string",
|
|
60
|
+
enum: [
|
|
61
|
+
"base64_encode", "base64_decode",
|
|
62
|
+
"url_encode", "url_decode",
|
|
63
|
+
"html_encode", "html_decode",
|
|
64
|
+
"hex_encode", "hex_decode",
|
|
65
|
+
"binary_encode", "binary_decode",
|
|
66
|
+
"detect",
|
|
67
|
+
],
|
|
68
|
+
description: "Encoding/decoding action to perform",
|
|
69
|
+
},
|
|
70
|
+
text: { type: "string", description: "Text to encode, decode, or detect" },
|
|
71
|
+
},
|
|
72
|
+
required: ["action", "text"],
|
|
73
|
+
},
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
name: "generate_id",
|
|
77
|
+
description: "Generate unique identifiers: UUID v4, nanoid, ULID, CUID, or random strings with configurable length and charset.",
|
|
78
|
+
inputSchema: {
|
|
79
|
+
type: "object",
|
|
80
|
+
properties: {
|
|
81
|
+
type: {
|
|
82
|
+
type: "string",
|
|
83
|
+
enum: ["uuid", "nanoid", "ulid", "cuid", "random"],
|
|
84
|
+
description: "Type of ID to generate",
|
|
85
|
+
},
|
|
86
|
+
count: { type: "number", description: "Number of IDs to generate (max 100). Default: 1" },
|
|
87
|
+
length: { type: "number", description: "Length for nanoid or random string. Default: 21 for nanoid, 16 for random" },
|
|
88
|
+
charset: {
|
|
89
|
+
type: "string",
|
|
90
|
+
description: "Charset for random strings: alphanumeric, alpha, numeric, hex, lowercase, uppercase, symbols, all, or a custom string of characters. Default: alphanumeric",
|
|
91
|
+
},
|
|
92
|
+
},
|
|
93
|
+
required: ["type"],
|
|
94
|
+
},
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
name: "password",
|
|
98
|
+
description: "Generate secure passwords with configurable options, or check password strength with entropy calculation and crack time estimation.",
|
|
99
|
+
inputSchema: {
|
|
100
|
+
type: "object",
|
|
101
|
+
properties: {
|
|
102
|
+
action: {
|
|
103
|
+
type: "string",
|
|
104
|
+
enum: ["generate", "check_strength"],
|
|
105
|
+
description: "Action: generate a password or check strength of an existing one",
|
|
106
|
+
},
|
|
107
|
+
password: { type: "string", description: "Password to check (for check_strength action)" },
|
|
108
|
+
length: { type: "number", description: "Password length (for generate). Default: 16" },
|
|
109
|
+
uppercase: { type: "boolean", description: "Include uppercase letters. Default: true" },
|
|
110
|
+
lowercase: { type: "boolean", description: "Include lowercase letters. Default: true" },
|
|
111
|
+
digits: { type: "boolean", description: "Include digits. Default: true" },
|
|
112
|
+
symbols: { type: "boolean", description: "Include symbols. Default: true" },
|
|
113
|
+
exclude_ambiguous: {
|
|
114
|
+
type: "boolean",
|
|
115
|
+
description: "Exclude ambiguous characters (0, O, l, I, 1). Default: false",
|
|
116
|
+
},
|
|
117
|
+
count: { type: "number", description: "Number of passwords to generate (max 100). Default: 1" },
|
|
118
|
+
},
|
|
119
|
+
required: ["action"],
|
|
120
|
+
},
|
|
121
|
+
},
|
|
122
|
+
{
|
|
123
|
+
name: "jwt",
|
|
124
|
+
description: "Decode JWT tokens to inspect header and payload, check expiry status, or create unsigned JWTs for testing purposes. Not for production authentication.",
|
|
125
|
+
inputSchema: {
|
|
126
|
+
type: "object",
|
|
127
|
+
properties: {
|
|
128
|
+
action: {
|
|
129
|
+
type: "string",
|
|
130
|
+
enum: ["decode", "check_expiry", "create_unsigned"],
|
|
131
|
+
description: "Action: decode (full decode), check_expiry (just expiry info), create_unsigned (create test token)",
|
|
132
|
+
},
|
|
133
|
+
token: { type: "string", description: "JWT token string (for decode and check_expiry)" },
|
|
134
|
+
payload: {
|
|
135
|
+
type: "object",
|
|
136
|
+
description: "Payload object for creating unsigned JWT (for create_unsigned)",
|
|
137
|
+
},
|
|
138
|
+
expires_in_seconds: {
|
|
139
|
+
type: "number",
|
|
140
|
+
description: "Expiration time in seconds from now (for create_unsigned)",
|
|
141
|
+
},
|
|
142
|
+
},
|
|
143
|
+
required: ["action"],
|
|
144
|
+
},
|
|
145
|
+
},
|
|
146
|
+
],
|
|
147
|
+
}));
|
|
148
|
+
// Handle tool calls
|
|
149
|
+
server.setRequestHandler(types_js_1.CallToolRequestSchema, async (request) => {
|
|
150
|
+
const { name, arguments: args } = request.params;
|
|
151
|
+
try {
|
|
152
|
+
switch (name) {
|
|
153
|
+
case "hash": {
|
|
154
|
+
const action = args?.action;
|
|
155
|
+
const encoding = args?.encoding || "hex";
|
|
156
|
+
switch (action) {
|
|
157
|
+
case "hash": {
|
|
158
|
+
const text = args?.text;
|
|
159
|
+
if (!text)
|
|
160
|
+
throw new Error("'text' is required for hash action");
|
|
161
|
+
const algorithm = args?.algorithm || "sha256";
|
|
162
|
+
const result = (0, hash_js_1.hashText)(text, algorithm, encoding);
|
|
163
|
+
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
164
|
+
}
|
|
165
|
+
case "hmac": {
|
|
166
|
+
const text = args?.text;
|
|
167
|
+
const key = args?.key;
|
|
168
|
+
if (!text)
|
|
169
|
+
throw new Error("'text' is required for hmac action");
|
|
170
|
+
if (!key)
|
|
171
|
+
throw new Error("'key' is required for hmac action");
|
|
172
|
+
const algorithm = args?.algorithm || "sha256";
|
|
173
|
+
const result = (0, hash_js_1.hmacText)(text, key, algorithm, encoding);
|
|
174
|
+
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
175
|
+
}
|
|
176
|
+
case "compare": {
|
|
177
|
+
const h1 = args?.hash1;
|
|
178
|
+
const h2 = args?.hash2;
|
|
179
|
+
if (!h1 || !h2)
|
|
180
|
+
throw new Error("'hash1' and 'hash2' are required for compare action");
|
|
181
|
+
const result = (0, hash_js_1.compareHashes)(h1, h2);
|
|
182
|
+
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
183
|
+
}
|
|
184
|
+
case "hash_all": {
|
|
185
|
+
const text = args?.text;
|
|
186
|
+
if (!text)
|
|
187
|
+
throw new Error("'text' is required for hash_all action");
|
|
188
|
+
const result = (0, hash_js_1.hashMultiple)(text, encoding);
|
|
189
|
+
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
190
|
+
}
|
|
191
|
+
default:
|
|
192
|
+
throw new Error(`Unknown hash action: ${action}`);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
case "encode_decode": {
|
|
196
|
+
const action = args?.action;
|
|
197
|
+
const text = args?.text;
|
|
198
|
+
if (!text)
|
|
199
|
+
throw new Error("'text' is required");
|
|
200
|
+
let result;
|
|
201
|
+
switch (action) {
|
|
202
|
+
case "base64_encode":
|
|
203
|
+
result = (0, encode_decode_js_1.base64Encode)(text);
|
|
204
|
+
break;
|
|
205
|
+
case "base64_decode":
|
|
206
|
+
result = (0, encode_decode_js_1.base64Decode)(text);
|
|
207
|
+
break;
|
|
208
|
+
case "url_encode":
|
|
209
|
+
result = (0, encode_decode_js_1.urlEncode)(text);
|
|
210
|
+
break;
|
|
211
|
+
case "url_decode":
|
|
212
|
+
result = (0, encode_decode_js_1.urlDecode)(text);
|
|
213
|
+
break;
|
|
214
|
+
case "html_encode":
|
|
215
|
+
result = (0, encode_decode_js_1.htmlEntitiesEncode)(text);
|
|
216
|
+
break;
|
|
217
|
+
case "html_decode":
|
|
218
|
+
result = (0, encode_decode_js_1.htmlEntitiesDecode)(text);
|
|
219
|
+
break;
|
|
220
|
+
case "hex_encode":
|
|
221
|
+
result = (0, encode_decode_js_1.hexEncode)(text);
|
|
222
|
+
break;
|
|
223
|
+
case "hex_decode":
|
|
224
|
+
result = (0, encode_decode_js_1.hexDecode)(text);
|
|
225
|
+
break;
|
|
226
|
+
case "binary_encode":
|
|
227
|
+
result = (0, encode_decode_js_1.binaryEncode)(text);
|
|
228
|
+
break;
|
|
229
|
+
case "binary_decode":
|
|
230
|
+
result = (0, encode_decode_js_1.binaryDecode)(text);
|
|
231
|
+
break;
|
|
232
|
+
case "detect":
|
|
233
|
+
result = (0, encode_decode_js_1.detectEncoding)(text);
|
|
234
|
+
break;
|
|
235
|
+
default: throw new Error(`Unknown encode_decode action: ${action}`);
|
|
236
|
+
}
|
|
237
|
+
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
238
|
+
}
|
|
239
|
+
case "generate_id": {
|
|
240
|
+
const type = args?.type;
|
|
241
|
+
const count = args?.count || 1;
|
|
242
|
+
let result;
|
|
243
|
+
switch (type) {
|
|
244
|
+
case "uuid":
|
|
245
|
+
result = (0, uuid_generator_js_1.generateUUIDv4)(count);
|
|
246
|
+
break;
|
|
247
|
+
case "nanoid": {
|
|
248
|
+
const length = args?.length || 21;
|
|
249
|
+
result = (0, uuid_generator_js_1.generateNanoid)(length, count);
|
|
250
|
+
break;
|
|
251
|
+
}
|
|
252
|
+
case "ulid":
|
|
253
|
+
result = (0, uuid_generator_js_1.generateULID)(count);
|
|
254
|
+
break;
|
|
255
|
+
case "cuid":
|
|
256
|
+
result = (0, uuid_generator_js_1.generateCUID)(count);
|
|
257
|
+
break;
|
|
258
|
+
case "random": {
|
|
259
|
+
const length = args?.length || 16;
|
|
260
|
+
const charset = args?.charset || "alphanumeric";
|
|
261
|
+
result = (0, uuid_generator_js_1.generateRandomString)(length, charset, count);
|
|
262
|
+
break;
|
|
263
|
+
}
|
|
264
|
+
default: throw new Error(`Unknown ID type: ${type}`);
|
|
265
|
+
}
|
|
266
|
+
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
267
|
+
}
|
|
268
|
+
case "password": {
|
|
269
|
+
const action = args?.action;
|
|
270
|
+
switch (action) {
|
|
271
|
+
case "generate": {
|
|
272
|
+
const result = (0, password_tools_js_1.generatePassword)({
|
|
273
|
+
length: args?.length,
|
|
274
|
+
uppercase: args?.uppercase,
|
|
275
|
+
lowercase: args?.lowercase,
|
|
276
|
+
digits: args?.digits,
|
|
277
|
+
symbols: args?.symbols,
|
|
278
|
+
exclude_ambiguous: args?.exclude_ambiguous,
|
|
279
|
+
count: args?.count,
|
|
280
|
+
});
|
|
281
|
+
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
282
|
+
}
|
|
283
|
+
case "check_strength": {
|
|
284
|
+
const password = args?.password;
|
|
285
|
+
if (!password)
|
|
286
|
+
throw new Error("'password' is required for check_strength action");
|
|
287
|
+
const result = (0, password_tools_js_1.checkPasswordStrength)(password);
|
|
288
|
+
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
289
|
+
}
|
|
290
|
+
default:
|
|
291
|
+
throw new Error(`Unknown password action: ${action}`);
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
case "jwt": {
|
|
295
|
+
const action = args?.action;
|
|
296
|
+
switch (action) {
|
|
297
|
+
case "decode": {
|
|
298
|
+
const token = args?.token;
|
|
299
|
+
if (!token)
|
|
300
|
+
throw new Error("'token' is required for decode action");
|
|
301
|
+
const result = (0, jwt_tools_js_1.decodeJWT)(token);
|
|
302
|
+
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
303
|
+
}
|
|
304
|
+
case "check_expiry": {
|
|
305
|
+
const token = args?.token;
|
|
306
|
+
if (!token)
|
|
307
|
+
throw new Error("'token' is required for check_expiry action");
|
|
308
|
+
const result = (0, jwt_tools_js_1.checkJWTExpiry)(token);
|
|
309
|
+
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
310
|
+
}
|
|
311
|
+
case "create_unsigned": {
|
|
312
|
+
const payload = args?.payload || {};
|
|
313
|
+
const expiresIn = args?.expires_in_seconds;
|
|
314
|
+
const result = (0, jwt_tools_js_1.createUnsignedJWT)(payload, expiresIn);
|
|
315
|
+
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
316
|
+
}
|
|
317
|
+
default:
|
|
318
|
+
throw new Error(`Unknown jwt action: ${action}`);
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
default:
|
|
322
|
+
throw new Error(`Unknown tool: ${name}`);
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
catch (error) {
|
|
326
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
327
|
+
return {
|
|
328
|
+
content: [{ type: "text", text: `Error: ${message}` }],
|
|
329
|
+
isError: true,
|
|
330
|
+
};
|
|
331
|
+
}
|
|
332
|
+
});
|
|
333
|
+
// Start server
|
|
334
|
+
async function main() {
|
|
335
|
+
const transport = new stdio_js_1.StdioServerTransport();
|
|
336
|
+
await server.connect(transport);
|
|
337
|
+
console.error("MCP Crypto Tools server running on stdio");
|
|
338
|
+
}
|
|
339
|
+
main().catch(console.error);
|
|
340
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
export declare function base64Encode(text: string): {
|
|
2
|
+
encoded: string;
|
|
3
|
+
original_length: number;
|
|
4
|
+
};
|
|
5
|
+
export declare function base64Decode(encoded: string): {
|
|
6
|
+
decoded: string;
|
|
7
|
+
encoded_length: number;
|
|
8
|
+
};
|
|
9
|
+
export declare function urlEncode(text: string): {
|
|
10
|
+
encoded: string;
|
|
11
|
+
};
|
|
12
|
+
export declare function urlDecode(encoded: string): {
|
|
13
|
+
decoded: string;
|
|
14
|
+
};
|
|
15
|
+
export declare function htmlEntitiesEncode(text: string): {
|
|
16
|
+
encoded: string;
|
|
17
|
+
};
|
|
18
|
+
export declare function htmlEntitiesDecode(text: string): {
|
|
19
|
+
decoded: string;
|
|
20
|
+
};
|
|
21
|
+
export declare function hexEncode(text: string): {
|
|
22
|
+
encoded: string;
|
|
23
|
+
};
|
|
24
|
+
export declare function hexDecode(hex: string): {
|
|
25
|
+
decoded: string;
|
|
26
|
+
};
|
|
27
|
+
export declare function binaryEncode(text: string): {
|
|
28
|
+
encoded: string;
|
|
29
|
+
};
|
|
30
|
+
export declare function binaryDecode(binary: string): {
|
|
31
|
+
decoded: string;
|
|
32
|
+
};
|
|
33
|
+
interface DetectionResult {
|
|
34
|
+
input: string;
|
|
35
|
+
detected_formats: string[];
|
|
36
|
+
analysis: Record<string, string>;
|
|
37
|
+
}
|
|
38
|
+
export declare function detectEncoding(text: string): DetectionResult;
|
|
39
|
+
export {};
|
|
40
|
+
//# sourceMappingURL=encode-decode.d.ts.map
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.base64Encode = base64Encode;
|
|
4
|
+
exports.base64Decode = base64Decode;
|
|
5
|
+
exports.urlEncode = urlEncode;
|
|
6
|
+
exports.urlDecode = urlDecode;
|
|
7
|
+
exports.htmlEntitiesEncode = htmlEntitiesEncode;
|
|
8
|
+
exports.htmlEntitiesDecode = htmlEntitiesDecode;
|
|
9
|
+
exports.hexEncode = hexEncode;
|
|
10
|
+
exports.hexDecode = hexDecode;
|
|
11
|
+
exports.binaryEncode = binaryEncode;
|
|
12
|
+
exports.binaryDecode = binaryDecode;
|
|
13
|
+
exports.detectEncoding = detectEncoding;
|
|
14
|
+
const HTML_ENTITY_MAP = {
|
|
15
|
+
"&": "&",
|
|
16
|
+
"<": "<",
|
|
17
|
+
">": ">",
|
|
18
|
+
'"': """,
|
|
19
|
+
"'": "'",
|
|
20
|
+
};
|
|
21
|
+
const HTML_ENTITY_REVERSE = {};
|
|
22
|
+
for (const [char, entity] of Object.entries(HTML_ENTITY_MAP)) {
|
|
23
|
+
HTML_ENTITY_REVERSE[entity] = char;
|
|
24
|
+
}
|
|
25
|
+
function base64Encode(text) {
|
|
26
|
+
return {
|
|
27
|
+
encoded: Buffer.from(text, "utf-8").toString("base64"),
|
|
28
|
+
original_length: text.length,
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
function base64Decode(encoded) {
|
|
32
|
+
return {
|
|
33
|
+
decoded: Buffer.from(encoded, "base64").toString("utf-8"),
|
|
34
|
+
encoded_length: encoded.length,
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
function urlEncode(text) {
|
|
38
|
+
return { encoded: encodeURIComponent(text) };
|
|
39
|
+
}
|
|
40
|
+
function urlDecode(encoded) {
|
|
41
|
+
return { decoded: decodeURIComponent(encoded) };
|
|
42
|
+
}
|
|
43
|
+
function htmlEntitiesEncode(text) {
|
|
44
|
+
const encoded = text.replace(/[&<>"']/g, (ch) => HTML_ENTITY_MAP[ch] || ch);
|
|
45
|
+
return { encoded };
|
|
46
|
+
}
|
|
47
|
+
function htmlEntitiesDecode(text) {
|
|
48
|
+
let decoded = text;
|
|
49
|
+
for (const [entity, char] of Object.entries(HTML_ENTITY_REVERSE)) {
|
|
50
|
+
decoded = decoded.split(entity).join(char);
|
|
51
|
+
}
|
|
52
|
+
// Handle numeric entities
|
|
53
|
+
decoded = decoded.replace(/&#(\d+);/g, (_, num) => String.fromCharCode(parseInt(num, 10)));
|
|
54
|
+
decoded = decoded.replace(/&#x([0-9a-fA-F]+);/g, (_, hex) => String.fromCharCode(parseInt(hex, 16)));
|
|
55
|
+
return { decoded };
|
|
56
|
+
}
|
|
57
|
+
function hexEncode(text) {
|
|
58
|
+
return { encoded: Buffer.from(text, "utf-8").toString("hex") };
|
|
59
|
+
}
|
|
60
|
+
function hexDecode(hex) {
|
|
61
|
+
const cleaned = hex.replace(/\s+/g, "").replace(/^0x/i, "");
|
|
62
|
+
if (!/^[0-9a-fA-F]*$/.test(cleaned) || cleaned.length % 2 !== 0) {
|
|
63
|
+
throw new Error("Invalid hex string");
|
|
64
|
+
}
|
|
65
|
+
return { decoded: Buffer.from(cleaned, "hex").toString("utf-8") };
|
|
66
|
+
}
|
|
67
|
+
function binaryEncode(text) {
|
|
68
|
+
const binary = Array.from(Buffer.from(text, "utf-8"))
|
|
69
|
+
.map((b) => b.toString(2).padStart(8, "0"))
|
|
70
|
+
.join(" ");
|
|
71
|
+
return { encoded: binary };
|
|
72
|
+
}
|
|
73
|
+
function binaryDecode(binary) {
|
|
74
|
+
const cleaned = binary.replace(/[^01\s]/g, "");
|
|
75
|
+
const bytes = cleaned.split(/\s+/).filter(Boolean);
|
|
76
|
+
for (const b of bytes) {
|
|
77
|
+
if (b.length !== 8)
|
|
78
|
+
throw new Error(`Invalid binary octet: "${b}" (must be 8 bits)`);
|
|
79
|
+
}
|
|
80
|
+
const buf = Buffer.from(bytes.map((b) => parseInt(b, 2)));
|
|
81
|
+
return { decoded: buf.toString("utf-8") };
|
|
82
|
+
}
|
|
83
|
+
function detectEncoding(text) {
|
|
84
|
+
const detected = [];
|
|
85
|
+
const analysis = {};
|
|
86
|
+
const trimmed = text.trim();
|
|
87
|
+
// Base64 check
|
|
88
|
+
if (/^[A-Za-z0-9+/]+=*$/.test(trimmed) && trimmed.length >= 4 && trimmed.length % 4 === 0) {
|
|
89
|
+
detected.push("base64");
|
|
90
|
+
try {
|
|
91
|
+
analysis["base64_decoded"] = Buffer.from(trimmed, "base64").toString("utf-8");
|
|
92
|
+
}
|
|
93
|
+
catch {
|
|
94
|
+
// not valid base64
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
// Hex check
|
|
98
|
+
if (/^(0x)?[0-9a-fA-F]+$/i.test(trimmed) && trimmed.replace(/^0x/i, "").length % 2 === 0) {
|
|
99
|
+
detected.push("hex");
|
|
100
|
+
try {
|
|
101
|
+
analysis["hex_decoded"] = Buffer.from(trimmed.replace(/^0x/i, ""), "hex").toString("utf-8");
|
|
102
|
+
}
|
|
103
|
+
catch {
|
|
104
|
+
// not valid hex
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
// URL encoded check
|
|
108
|
+
if (/%[0-9A-Fa-f]{2}/.test(trimmed)) {
|
|
109
|
+
detected.push("url_encoded");
|
|
110
|
+
try {
|
|
111
|
+
analysis["url_decoded"] = decodeURIComponent(trimmed);
|
|
112
|
+
}
|
|
113
|
+
catch {
|
|
114
|
+
// not valid url encoding
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
// HTML entities check
|
|
118
|
+
if (/&(?:#\d+|#x[0-9a-fA-F]+|[a-zA-Z]+);/.test(trimmed)) {
|
|
119
|
+
detected.push("html_entities");
|
|
120
|
+
analysis["html_decoded"] = htmlEntitiesDecode(trimmed).decoded;
|
|
121
|
+
}
|
|
122
|
+
// Binary check
|
|
123
|
+
if (/^[01]{8}(\s+[01]{8})*$/.test(trimmed)) {
|
|
124
|
+
detected.push("binary");
|
|
125
|
+
try {
|
|
126
|
+
analysis["binary_decoded"] = binaryDecode(trimmed).decoded;
|
|
127
|
+
}
|
|
128
|
+
catch {
|
|
129
|
+
// not valid binary
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
// JWT check
|
|
133
|
+
if (/^[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]*$/.test(trimmed)) {
|
|
134
|
+
detected.push("jwt");
|
|
135
|
+
}
|
|
136
|
+
if (detected.length === 0) {
|
|
137
|
+
detected.push("plain_text");
|
|
138
|
+
}
|
|
139
|
+
return { input: trimmed.substring(0, 100), detected_formats: detected, analysis };
|
|
140
|
+
}
|
|
141
|
+
//# sourceMappingURL=encode-decode.js.map
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export declare function hashText(text: string, algorithm: string, encoding?: "hex" | "base64"): {
|
|
2
|
+
algorithm: string;
|
|
3
|
+
hash: string;
|
|
4
|
+
encoding: string;
|
|
5
|
+
input_length: number;
|
|
6
|
+
};
|
|
7
|
+
export declare function hmacText(text: string, key: string, algorithm: string, encoding?: "hex" | "base64"): {
|
|
8
|
+
algorithm: string;
|
|
9
|
+
hmac: string;
|
|
10
|
+
encoding: string;
|
|
11
|
+
input_length: number;
|
|
12
|
+
};
|
|
13
|
+
export declare function compareHashes(hash1: string, hash2: string): {
|
|
14
|
+
match: boolean;
|
|
15
|
+
hash1: string;
|
|
16
|
+
hash2: string;
|
|
17
|
+
};
|
|
18
|
+
export declare function hashMultiple(text: string, encoding?: "hex" | "base64"): Record<string, string>;
|
|
19
|
+
//# sourceMappingURL=hash.d.ts.map
|