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

Tags:

Code Golf