0

I’m looking for a way to invert all bits in a file, preferably using Windows-integrated tools. How do I go about doing that?

In essence, a file with contents 1100101 would become 0011010.

2
  • Windows does not have an integrated tool that does this. Any good hex editor will do this.
    – Ramhound
    Apr 25, 2015 at 18:23
  • 1
    Write your own code using VBScript or PowerShell.
    – Karan
    Apr 25, 2015 at 18:52

3 Answers 3

1

You can try with the following powershell line :

[byte[]](gc in.bin -Encoding Byte| % {$_ -bxor 0xFF })|sc out.bin -Encoding Byte

Think to replace 'in.bin' and 'out.bin' by your input and output filename.

A more explicit version (without alias):

[byte[]](Get-Content in.bin -Encoding Byte| ForEach {$_ -bxor 0xFF })| Set-Content out.bin -Encoding Byte

The command do a XOR with each byte one by one to invert bit in file.

In powershell version 6 and more, you need to replace "-Enconding Byte" by "-AsByteStream"

[byte[]](Get-Content in.bin -AsByteStream| ForEach {$_ -bxor 0xFF })| Set-Content out.bin -AsByteStream
1
  • why use -bxor instead of -bnot?
    – phuclv
    Jun 25, 2022 at 4:42
0

FileInvert (GUI + CLI) can invert the bits. Also see this question.

0

I've heard it said that "so-called operating systems are just bootloaders for Firefox/Chrome, which is your real operating system"...

preferably using Windows-integrated tools

Paste this into Notepad, Save As Type: All Documents, name it invert_file.html, and open it in Edge version 15 or newer (Firefox and Chrome also work):

<script>

function _invert_arrbuf(arrbuf) {
    // Takes in an ArrayBuffer
    // and synchronously inverts every bit of it in-place
    // (it also returns it anyway, for convenience)
    let view = new Uint8Array(arrbuf);
    let len = view.length;
    if ( len > Number.MAX_SAFE_INTEGER ) throw {error: `File too large (${len} > Number.MAX_SAFE_INTEGER).`}; // https://stackoverflow.com/q/72807979
    for ( let i = 0 ; i < len ; i++ ) {
        view[i] ^= -1;
    }
    return arrbuf;
}


function to_async(f) {
    // Converts long-running synchronous or CPU-bound
    // function or eval-able string
    // into an asynchronous WebWorker-based function
    // to avoid blocking the UI

    if ( !('Worker' in window) ) return f;
    let src = f.toString();
    let src_worker = [
        "self.addEventListener('message', async m => { ",
        "let arguments = m.data.arguments, result; ",
        "try { ",
        "result = await (\n",
        src,
        "\n)(...arguments); ",
        "self.postMessage({result: result}, [result].filter(x => typeof x === 'object')); ",
        "} catch (error) { self.postMessage({error: error}, arguments.filter(x => typeof x === 'object')); } ",
        "}, {once: true});"
    ];

    let src_worker_url;
    if ('FinalizationRegistry' in window) {
        src_worker_url = URL.createObjectURL(new Blob(src_worker, {type: 'application/javascript'}));
    } else {
        src_worker_url = 'data:application/javascript,' + encodeURIComponent(src_worker.join(String()));
    }

    async function g() {
        let w = new Worker(src_worker_url);
        let p = new Promise((resolve, reject) => w.addEventListener('message', m => m.data.hasOwnProperty('result') ? resolve(m.data.result) : reject(m.data.error), {once: true}));
        w.postMessage({arguments: Array.from(arguments)}, Array.from(arguments).filter(x => typeof x === 'object'));
        let result = await p;
        return result;
    }
    if ( src_worker_url.startsWith('blob:') ) new FinalizationRegistry(URL.revokeObjectURL).register(g, src_worker_url);
    return g;
}


var invert_arrbuf = to_async(_invert_arrbuf);


function create_download_link(file, linktext) {
    // Takes in a File (or Blob) object
    // and returns a "self-destructing" one-use link to it
    // as a DOM element
    let a = document.createElement('a');
    let u = URL.createObjectURL(file);
    console.debug(u);
    a.href = u;
    if ( file.name ) {
        a.setAttribute('download', file.name);
    }
    if (linktext === undefined) {
        linktext = `Download ${file.name} (${file.size} bytes)`;
    }
    a.textContent = linktext;
    a.addEventListener('click', ev => setTimeout(() => {ev.target.parentNode.removeChild(ev.target); URL.revokeObjectURL(ev.target.href);}, 1));
    return a;
}


async function main(file) {
    // Takes in a File,
    // and returns a File with contents bit-flipped
    // and a name with .not.bin stripped if not present and appended if present

    let [basename, suffix] = file.name.match(/(.*?)(\.not\.bin)?$/).slice(1);
    let new_filename = basename + (suffix ? '' : '.not.bin');

    let new_arrbuf = await file.arrayBuffer();
    delete file; // pray to the gods of garbage collection...
    new_arrbuf = await invert_arrbuf(new_arrbuf);

    let new_file = new File([new_arrbuf], new_filename);
    delete new_arrbuf; // ...that we might use less than 3x the necessary RAM
    // -- If you intend to manipulate files larger than about half the available RAM,
    // see https://stackoverflow.com/questions/39682465
    // or consider using 3rd-party software like Python or Elixir
    // via RAM-friendly APIs like Iterators or Streams
    return new_file;
}

async function form_handler(ev) {
    // Takes in a Submit event,
    // clears the form's file input,
    // feeds the input file to main(),
    // and appends to the document body
    // a self-destructing link to the result.
    // If main() errors out, a red warning message
    // will be appended instead.

    let form = ev.target;
    let input = form.elements.file;
    let file = input.files[0];
    input.value = null;

    let e = document.createElement('div');
    let e1 = document.createElement('span');
    e1.textContent = `Processing ${file.name}\u2026`;
    e.appendChild(e1);
    document.body.appendChild(e);

    let new_file;
    try {
        new_file = await main(file);
    } catch (err) {
        e1.textContent = `Failed processing ${file.name}!`;
        e1.classList.add('error');
        e1.addEventListener('click', () => e.parentNode.removeChild(e));
        throw err;
    }

    let a = create_download_link(new_file);
    a.addEventListener('click', () => e.parentNode.removeChild(e));
    e.replaceChild(a, e1);
}

</script>

<style>span.error { color: red; }</style>

<form action="javascript:{form_handler({target: document.getElementById('main_form')});}" id="main_form">
<input type="file" name="file" />
<input type="submit" name="submit" value="Encrypt (ECB with blocksize &#x215b;B)" />
</form>
0

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .