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.

bertieb
  • 7,543

3 Answers3

1

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} &gt; 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 = [
    &quot;self.addEventListener('message', async m =&gt; { &quot;,
    &quot;let arguments = m.data.arguments, result; &quot;,
    &quot;try { &quot;,
    &quot;result = await (\n&quot;,
    src,
    &quot;\n)(...arguments); &quot;,
    &quot;self.postMessage({result: result}, [result].filter(x =&gt; typeof x === 'object')); &quot;,
    &quot;} catch (error) { self.postMessage({error: error}, arguments.filter(x =&gt; typeof x === 'object')); } &quot;,
    &quot;}, {once: true});&quot;
];

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) =&gt; w.addEventListener('message', m =&gt; 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 =&gt; 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', () =&gt; e.parentNode.removeChild(e));
    throw err;
}

let a = create_download_link(new_file);
a.addEventListener('click', () =&gt; 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>

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
S. Brottes
  • 1,289
0

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

tejasvi
  • 328