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 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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.