Shortest code to secure wipe a disk
On a linux system there's no need for special handling of devices. Just use the device file interface.
Python 3 (byte strings) - 141 bytes
d=input()
f=open(d,'r+b')
z=f.seek
z(0,2)
s=f.tell()
i=0
while i<2:
z(0);f.write([b'\0',b'\xff'][i]*s);f.flush();z(0)
if f.read()==x:i+=1
It's fairly straightforward, and not really optimised heavily, but it works. Here's a basic rundown.
- Get input (device file path)
- Open device file
- Seek to the end, get filesize (block devices are always their real size)
- enter write-and-check loop
- construct 0-bit and 1-bit strings (x)
- write bitstring
- flush output (I could have set buffering=0 but this is shorter)
- test file against x, and increment step of loop if it passes
exit loop when the increment is high enough
As a bonus, you could modify this for any set and number of byte-modification patterns, like 0x55/0xaa for stronger overwriting effects.
I did actually test this on a device file, using loopback. However, I'm not 100% sure the checking actually works. It might be necessary to close and reopen the file each pass, due to buffering behaviors. I would hope flush prevents this.
*edited to incorporate some suggestions in the comments
C (clang), -DZ=lseek(d,0
+ 139 = 152 bytes
g,j,x,d,s,i,c;f(n){x=0;d=open(n,2);s=Z,2);for(j=2;j--;x++){Z,0);for(i=s;i--;write(d,&x,1));Z,0);for(i=s;i--;read(d,&c,1),c!=x&&x--&&j--);}}
Try it online!
Takes the filename as an argument
Ungolfed:
#include <unistd.h>
int g,j,x,d,s,i,c;
void f(char*n){
x=0; /*Byte to write*/
d=open(n,O_RDWR);
s=lseek(d,0,SEEK_END); /*Get size of file*/
j=0;
for(j=0;j<2;j++){
/*Write Pass*/
lseek(d,0,SEEK_SET); /*Start writing from start of file*/
for(i=0;i<s;i++){
write(d,&x,1);
}
/*Verification Pass*/
lseek(d,0,SEEK_SET);
for(i=0;i<s;i++){
read(d,&c,1);
if(c!=x)x--,j--; /*If verification fails, repeat loop with the same value*/
}
x++;
}
}
x86 machine code (Linux), 116 109 106 bytes
00000000: 89cb 6a02 5999 894c 24f4 b005 cd80 505b ..j.Y..L$.....P[
00000010: 536a 025a 31c9 b013 cd80 89c6 5b53 9931 Sj.Z1.......[S.1
00000020: c9b0 13cd 8089 f75b 53b2 018d 4c24 f8b0 .......[S...L$..
00000030: 04cd 804e 75f1 5b53 9931 c9b0 13cd 8089 ...Nu.[S.1......
00000040: fe5b 538d 4c24 f4b2 01b0 03cd 804e 740c .[S.L$.......Nt.
00000050: 8a44 24f8 3844 24f4 74e7 ebb3 89fe b001 .D$.8D$.t.......
00000060: 8644 24f8 3c01 75a7 58c3 .D$.<.u.X.
Function that takes filename as argument, uses fastcall convention.
Assembly (NASM):
section .text
global func
func:
;open file
mov ebx, ecx ;first argument to func (filename)
push 0x2 ;flag O_RDWR
pop ecx ;pushing a constant is shorter than mov
cdq ;edx=mode=0
mov [esp-12], ecx ;set first byte (msg) to write to 0. msg later in esp-8, buf in esp-12
mov al, 5
int 0x80 ;syscall open
push eax ;save file descriptor
write_verify:
;get file size
pop ebx ;get fd
push ebx
push 0x2 ;flag SEEK_END
pop edx
xor ecx, ecx ;offset 0
mov al, 0x13
int 0x80 ;syscall lseek
mov esi, eax ;save file byte count in esi
;reset index of file to 0
pop ebx ;get fd
push ebx
cdq ;edx=flag SEEK_SET=0
xor ecx, ecx ;ecx=0
mov al, 0x13
int 0x80 ;syscall lseek
;***write pass***
mov edi, esi
write_loop: ;for each byte in byte count, write [msg]
;write to file
pop ebx ;file descriptor
push ebx
mov dl, 1 ;bytes to write
lea ecx, [esp-8] ;buffer to write from
mov al, 4
int 0x80 ;syscall write
dec esi ;decrement (byte count) to 0
jne write_loop ;while esi!=0, loop
;reset index of file to 0
pop ebx ;get fd
push ebx
cdq ;edx=SEEK_SET=0
xor ecx, ecx ;ecx=0
mov al, 0x13
int 0x80 ;syscall lseek
;***verification pass***
mov esi, edi
verify_loop: ;for each byte in byte count, verify written byte
pop ebx ;get fd
push ebx
lea ecx, [esp-12] ;buffer to store read byte
mov dl, 1 ;read 1 byte
mov al, 3
int 0x80 ;syscall read
dec esi
je end_verify ;at final byte, end verification
mov al, [esp-8]
cmp byte [esp-12],al
je verify_loop ;loop if expected value found
jmp write_verify ;if byte!=expected value, restart
end_verify:
mov esi, edi
mov al, 1
xchg byte [esp-8],al ;set new byte to write to 1
cmp al, 1
jne write_verify ;if old byte to write!=1, goto start
pop eax ;reset stack
ret
Try it online!
-7 bytes and -3 bytes thanks to @EasyasPi