{"id":2740,"date":"2019-10-28T11:56:58","date_gmt":"2019-10-28T10:56:58","guid":{"rendered":"https:\/\/solidt.eu\/site\/?p=2740"},"modified":"2026-06-01T16:08:20","modified_gmt":"2026-06-01T15:08:20","slug":"encode-decode-javascript-c-strings","status":"publish","type":"post","link":"https:\/\/solidt.eu\/site\/encode-decode-javascript-c-strings\/","title":{"rendered":"Encode\/Decode javascript\/C# strings"},"content":{"rendered":"\n<div class=\"wp-block-columns is-layout-flex wp-container-core-columns-is-layout-7387b849 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\">\n<h2 class=\"wp-block-heading\">Input<\/h2>\n\n\n        <div\n            class=\"niels-ace-editor wp-block-niels-ace-frontend-editor\"\n            id=\"aceInputEditor\"\n            data-language=\"text\"\n            data-theme=\"monokai\"\n            data-readonly=\"0\"\n            data-persist=\"1\"\n            data-persist-key=\"ace-editor-22f1d848cf1482cc2cd7b4e14d0e8167\"\n        >\n            <div class=\"niels-ace-editor__surface\" style=\"height: 320px;\"><\/div>\n            <textarea class=\"niels-ace-editor__source\"><\/textarea>\n        <\/div>\n        <\/div>\n\n\n\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\">\n<h2 class=\"wp-block-heading\">Output<\/h2>\n\n\n        <div\n            class=\"niels-ace-editor wp-block-niels-ace-frontend-editor\"\n            id=\"aceOutputEditor\"\n            data-language=\"javascript\"\n            data-theme=\"monokai\"\n            data-readonly=\"0\"\n            data-persist=\"1\"\n            data-persist-key=\"ace-editor-27b2abf2818accc8000bf1a41db2b2b8\"\n        >\n            <div class=\"niels-ace-editor__surface\" style=\"height: 320px;\"><\/div>\n            <textarea class=\"niels-ace-editor__source\"><\/textarea>\n        <\/div>\n        <\/div>\n<\/div>\n\n\n\n<style>  \n.my-grid {\n    display: grid;\n    grid-auto-flow: column;    \n    column-gap: 5px;\n    margin:10px\n}\n\n.auto-columns {\n\tgrid-auto-columns: max-content;\n}\n<\/style>\n<div class=\"my-grid auto-columns\">\n<button id=\"btnEncode\" type=\"button\">Encode<\/button>\n<button id=\"btnDecode\" type=\"button\">Decode<\/button>\n<button id=\"btnBuildString\" type=\"button\">BuildString<\/button>\n<button id=\"btnReverseBuildString\" type=\"button\">Reverse BuildString<\/button>\n<label>\n<input type=\"checkbox\" id=\"chkSingleQuote\">\nUse Single Quotes\n<label>\n<\/label><\/label><\/div>\n\n\n\n<div data-wp-context=\"{ &quot;autoclose&quot;: false, &quot;accordionItems&quot;: [] }\" data-wp-interactive=\"core\/accordion\" role=\"group\" class=\"wp-block-accordion is-layout-flow wp-block-accordion-is-layout-flow\">\n<div data-wp-class--is-open=\"state.isOpen\" data-wp-context=\"{ &quot;id&quot;: &quot;accordion-item-1&quot;, &quot;openByDefault&quot;: false }\" data-wp-init=\"callbacks.initAccordionItems\" data-wp-on-window--hashchange=\"callbacks.hashChange\" class=\"wp-block-accordion-item is-layout-flow wp-block-accordion-item-is-layout-flow\">\n<h3 class=\"wp-block-accordion-heading\"><button aria-expanded=\"false\" aria-controls=\"accordion-item-1-panel\" data-wp-bind--aria-expanded=\"state.isOpen\" data-wp-on--click=\"actions.toggle\" data-wp-on--keydown=\"actions.handleKeyDown\" id=\"accordion-item-1\" type=\"button\" class=\"wp-block-accordion-heading__toggle\"><span class=\"wp-block-accordion-heading__toggle-title\">Code<\/span><span class=\"wp-block-accordion-heading__toggle-icon\" aria-hidden=\"true\">+<\/span><\/button><\/h3>\n\n\n\n<div inert aria-labelledby=\"accordion-item-1\" data-wp-bind--inert=\"!state.isOpen\" id=\"accordion-item-1-panel\" role=\"region\" class=\"wp-block-accordion-panel is-layout-flow wp-block-accordion-panel-is-layout-flow\">\n<div style=\"height: 250px; position:relative; margin-bottom: 50px;\" class=\"wp-block-simple-code-block-ace\"><pre class=\"wp-block-simple-code-block-ace\" style=\"position:absolute;top:0;right:0;bottom:0;left:0\" data-mode=\"javascript\" data-theme=\"monokai\" data-fontsize=\"14\" data-lines=\"Infinity\" data-showlines=\"true\" data-copy=\"false\">\/*\n    Backspace is replaced with \\b\n    Newline is replaced with \\n\n    Tab is replaced with \\t\n    Carriage return is replaced with \\r\n    Form feed is replaced with \\f\n    Double quote is replaced with \\\"\n    Backslash is replaced with \\\\\n*\/\nconst $ = document.querySelector.bind(document);\nconst on = (e, evt, fn) => e.addEventListener(evt, fn);\nlet quote = '\"';\n\nconst encodeR = {\n    \"\\b\": \"\\\\b\",\n    \"\\n\": \"\\\\n\",\n    \"\\t\": \"\\\\t\",\n    \"\\r\": \"\\\\r\",\n    \"\\f\": \"\\\\f\",\n    \"\\\"\": \"\\\\\\\"\",\n    \"\\\\\": \"\\\\\\\\\",\n};\nconst decodeR = {\n    \"\\\\b\": \"\\b\",\n    \"\\\\n\": \"\\n\",\n    \"\\\\t\": \"\\t\",\n    \"\\\\r\": \"\\r\",\n    \"\\\\f\": \"\\f\",\n    \"\\\\\\\"\": \"\\\"\",\n    \"\\\\\\\\\": \"\\\\\"\n};\n\nconst switchQuote = () => {\n    const useSingleQuote = $(\"#chkSingleQuote\").checked;\n    quote = useSingleQuote ? \"'\" : '\"';\n\n    if (quote === \"'\") {\n        encodeR[\"\\'\"] = \"\\\\\\'\";\n        delete encodeR[\"\\\"\"];\n        decodeR[\"\\\\\\'\"] = \"\\'\";\n        delete decodeR[\"\\\\\\\"\"];\n    } else {\n        encodeR[\"\\\"\"] = \"\\\\\\\"\";\n        delete encodeR[\"\\'\"];\n        decodeR[\"\\\\\\\"\"] = \"\\\"\";\n        delete decodeR[\"\\\\\\'\"];\n    }\n}\n\nconst encode = (text) => {\n    let res = \"\";\n    for (const c of String(text)) {\n        if (c in encodeR) {\n            res += encodeR[c];\n        } else {\n            res += c;\n        }\n    }\n    return res;\n};\n\nconst decode = (text) => {\n    return String(text).replace(\/(\\\\.)\/gm, (group) => {\n        if (group in decodeR) {\n            return decodeR[group];\n        }\n        return group;\n    });\n};\n\nconst buildString = (text) => {\n    var lines = text.split('\\n');\n    return lines\n        .map(l => '\\t' + quote + encode(l) + quote)\n        .join(\",\\n\");\n};\n\nconst buildRust = (text) => {\n    var lines = text.split('\\n');\n    const body = lines\n        .map(l => '\\t' + quote + encode(l) + quote)\n        .join(\",\\n\");\n    return \"\/\/ Javascript \/ Rust\\nlet sql = [\\n\" + body + \"\\n].join(\\\"\\\\n\\\");\";\n};\n\n\/\/ reverse buildstring\nconst stringPart = \/\"(.*?[^\\\\])\"\/gm;\nconst stringPartSq = \/'(.*?[^\\\\])'\/gm;\nconst getMatches = (re, str) => {\n    let match, matches = [];\n    while (match = re.exec(str)) {\n        matches.push(match);\n    }\n    return matches;\n};\n\nconst reverseBuildString = (text) => {\n    const regEx = quote === \"'\" ? stringPartSq : stringPart;\n    const lines = text.split('\\n');\n    const resultLines = [];\n    for (const line of lines) {\n        const str = getMatches(regEx, line).map(m => decode(m[1])).join(\"\").trim();\n        if (str.length > 0) resultLines.push(str);\n    }\n    return resultLines.join(\"\\n\");\n};\n\nfunction copyStringToClipboard(string) {\n    function handler(event) {\n        event.clipboardData.setData('text\/plain', string);\n        event.preventDefault();\n        document.removeEventListener('copy', handler, true);\n    }\n    document.addEventListener('copy', handler, true);\n    document.execCommand('copy');\n}\n\non(window, \"DOMContentLoaded\", () => {\n    const btnEncode = $(\"#btnEncode\");\n    const btnDecode = $(\"#btnDecode\");\n    const btnBuildString = $(\"#btnBuildString\");\n    const btnReverseBuildString = $(\"#btnReverseBuildString\");\n\n    if (!btnEncode || !btnDecode || !btnBuildString || !btnReverseBuildString) {\n        return;\n    }\n\n    const prefix = \"\/\/ C#\\nvar sql = string.Join(Environment.NewLine, new string[] {\\n\";\n    const postfix = \"\\n});\";\n\n    const getEditor = (id) => {\n        const api = window.NielsAceFrontend;\n        if (!api || typeof api.getEditor !== \"function\") {\n            return null;\n        }\n        return api.getEditor(id);\n    };\n\n    const bindApp = (inputEditor, outputEditor) => {\n        if (!inputEditor || !outputEditor) {\n            return;\n        }\n\n        const readInput = () => String(inputEditor.getValue());\n\n        const writeOutput = (value) => {\n            outputEditor.setValue(value, -1);\n        };\n\n        outputEditor.setReadOnly(true);\n\n        function run(fn) {\n            return () => {\n                switchQuote();\n                const result = fn();\n                writeOutput(result);\n                copyStringToClipboard(result);\n            };\n        }\n\n        btnEncode.addEventListener(\"click\", run(() => encode(readInput().trim())));\n        btnDecode.addEventListener(\"click\", run(() => decode(readInput().trim())));\n        btnBuildString.addEventListener(\"click\", run(() => {\n            const source = readInput().trim();\n            const csharpOutput = prefix + buildString(source) + postfix;\n            const rustOutput = buildRust(source);\n            return csharpOutput + \"\\n\\n\" + rustOutput;\n        }));\n        btnReverseBuildString.addEventListener(\"click\", run(() => reverseBuildString(readInput().trim())));\n    };\n\n    const tryInit = (retriesLeft) => {\n        const inputEditor = getEditor(\"aceInputEditor\");\n        const outputEditor = getEditor(\"aceOutputEditor\");\n\n        if (inputEditor &amp;&amp; outputEditor) {\n            bindApp(inputEditor, outputEditor);\n            return;\n        }\n\n        if (retriesLeft &lt;= 0) {\n            return;\n        }\n\n        window.setTimeout(() => tryInit(retriesLeft - 1), 100);\n    };\n\n    tryInit(20);\n});<\/pre><\/div>\n<\/div>\n<\/div>\n<\/div>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Input Output Encode Decode BuildString Reverse BuildString Use Single Quotes<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":true,"template":"","format":"standard","meta":{"inline_featured_image":false,"footnotes":""},"categories":[6,5,4,1],"tags":[],"class_list":["post-2740","post","type-post","status-publish","format-standard","hentry","category-dotnet","category-javascript","category-programming","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/solidt.eu\/site\/wp-json\/wp\/v2\/posts\/2740","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/solidt.eu\/site\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/solidt.eu\/site\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/solidt.eu\/site\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/solidt.eu\/site\/wp-json\/wp\/v2\/comments?post=2740"}],"version-history":[{"count":33,"href":"https:\/\/solidt.eu\/site\/wp-json\/wp\/v2\/posts\/2740\/revisions"}],"predecessor-version":[{"id":10197,"href":"https:\/\/solidt.eu\/site\/wp-json\/wp\/v2\/posts\/2740\/revisions\/10197"}],"wp:attachment":[{"href":"https:\/\/solidt.eu\/site\/wp-json\/wp\/v2\/media?parent=2740"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/solidt.eu\/site\/wp-json\/wp\/v2\/categories?post=2740"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/solidt.eu\/site\/wp-json\/wp\/v2\/tags?post=2740"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}