diff --git a/index.html b/index.html index ab42131..05c58c0 100644 --- a/index.html +++ b/index.html @@ -85,6 +85,13 @@ > Tokenizer + @@ -389,6 +396,54 @@ + + +
+
+
+
+

Fuzzer mutate text into diverse payloads

+
+
+ + + +
+
+ + + + + + + +
+
+ + + +
+
+
+
+ #{{ i+1 }} + + +
+
+
+
+
+
diff --git a/js/app.js b/js/app.js index f4f6779..ee1273f 100644 --- a/js/app.js +++ b/js/app.js @@ -82,6 +82,19 @@ window.app = new Vue({ tokenizerCharCount: 0, tokenizerWordCount: 0, + // Fuzzer + fuzzerInput: '', + fuzzerCount: 20, + fuzzerSeed: '', + fuzzUseRandomMix: true, + fuzzZeroWidth: true, + fuzzUnicodeNoise: true, + fuzzZalgo: false, + fuzzWhitespace: true, + fuzzCasing: true, + fuzzEncodeShuffle: false, + fuzzerOutputs: [], + // History of copied content copyHistory: [], maxHistoryItems: 10, @@ -1702,6 +1715,74 @@ window.app = new Vue({ }); } , + // -------- Fuzzer -------- + seededRandomFactory(seedStr) { + if (!seedStr) return Math.random; + let h = 1779033703 ^ seedStr.length; + for (let i=0;i>> 19); + } + return function() { + h ^= h >>> 16; h = Math.imul(h, 2246822507); h ^= h >>> 13; h = Math.imul(h, 3266489909); h ^= h >>> 16; + return (h >>> 0) / 4294967296; + }; + }, + pick(arr, rnd) { return arr[Math.floor(rnd()*arr.length)]; }, + injectZeroWidth(text, rnd) { + const zw = ['\u200B','\u200C','\u200D','\u2060']; + return [...text].map(ch => (rnd()<0.2 ? ch+this.pick(zw,rnd) : ch)).join(''); + }, + injectUnicodeNoise(text, rnd) { + const marks = ['\u0301','\u0300','\u0302','\u0303','\u0308','\u0307','\u0304']; + return [...text].map(ch => (rnd()<0.15 ? ch+this.pick(marks,rnd) : ch)).join(''); + }, + whitespaceChaos(text, rnd) { + return text.replace(/\s/g, (m)=> (rnd()<0.5? m : (rnd()<0.5?'\t':'\u00A0'))); + }, + casingChaos(text, rnd) { + return [...text].map(c => /[a-z]/i.test(c)? (rnd()<0.5? c.toUpperCase():c.toLowerCase()) : c).join(''); + }, + encodeShuffle(text, rnd) { + const opts = ['base64','base32','hex','base58','base62','url']; + const t = this.pick(opts, rnd); + const tx = { + base64: ()=> window.transforms.base64.func(text), + base32: ()=> window.transforms.base32.func(text), + hex: ()=> window.transforms.hex.func(text), + base58: ()=> window.transforms.base58.func(text), + base62: ()=> window.transforms.base62.func(text), + url: ()=> window.transforms.url.func(text) + }; + return (tx[t]||(()=>text))(); + }, + generateFuzzCases() { + const src = String(this.fuzzerInput || ''); + if (!src) { this.fuzzerOutputs = []; return; } + const rnd = this.seededRandomFactory(String(this.fuzzerSeed||'')); + const out = []; + for (let i=0;iURL.revokeObjectURL(url), 200); + }, // Quick estimate of token count for Tokenade estimateTokenadeTokens() { // Roughly approximate tokens by estimated character length