Vou começar isso dizendo que bitwise complementando um disco não é um apagamento seguro, porque se alguém souber o que você fez, tudo o que eles têm a fazer é reverter o processo para restaurar o disco ao seu estado original.
Embora bash
tenha um operador de complemento, não creio que possa ser usado aqui porque você não pode trabalhar com bytes brutos sem alguma ferramenta adicional.
Aqui está um pequeno programa em C que servirá como um pipeline de complemento bit a bit:
#include <stdio.h>
#include <unistd.h>
#include <inttypes.h>
#define BUFSZ 4096
int main (void) {
unsigned char buffer[BUFSZ];
int i, check;
uint64_t total = 0;
while ((check = read(0, buffer, BUFSZ)) > 0) {
for (i = 0; i < check; i++) buffer[i] = ~buffer[i];
write(1, buffer, check);
total += check;
}
fprintf(stderr, "Bitcomp processed %lu bytes.\n", total);
return 0;
}
Compile isso:
gcc whatever.c -o bitcomp
Então:
dd if=something | ./bitcomp | dd of=something conv=notrunc
O conv=notrunc
(sem truncamento) é necessário ao gravar no mesmo arquivo que está sendo lido. Você pode não precisar dele para um dispositivo. Você também pode usar:
./bitcomp < something 1<> something
Onde 1<>
serve como a versão "não truncada" de >
(obrigado Stephane Chazelas). Esteja ciente de que o programa reporta ao erro padrão (descritor 2 para o shell), portanto, não redirecione 2>&1
etc.
Se você quiser ver o que quero dizer com reversível, execute-o em um arquivo de texto e execute-o novamente no mesmo arquivo de texto. Estará de volta do jeito que começou.