Código mais curto para proteger limpe um disco

9

Vamos escrever o código mais curto para executar uma variante simplificada do método de limpeza DoD 5220.22-M com apenas dois passes de gravação.

Qualquer linguagem de programação aceita, mas o uso de bibliotecas orientadas à limpeza de disco é proibido.

Aqui está como devemos implementá-lo no pseudocódigo:

Set x to 0

[Start]
'Write Pass
For each sector in disk write the content of x
'Verification Pass
For each sector in disk {
    If sector does not contain the content of x then goto [Start]
}
'Check whether we already did the pass with 1
If x is not 1 then {
    Set x to 1
    GoTo [Start]
}
Else end

Em outras palavras, esse código será executado duas vezes, com um passe de gravação e um passe de verificação 0e um passe de gravação e passe de verificação para 1.

Alguém ousado o suficiente para implementá-lo no estilo de código-golfe? ;)

MathuSum Mut
fonte
6
Duvido que isso obtenha respostas por causa da dificuldade em testar.
James
12
Sério, o que seu SSD fez com você para merecer esse tipo de tratamento? Matou toda a sua coleção de ursinhos de pelúcia ou algo assim?
R. Kap
2
Realmente quero tentar resolver isso ... também realmente não quero sacrificar meu HDD para testá-lo.
Michelfrancis Bustillos
6
Estou votando para encerrar esta questão como fora de tópico, porque esse desafio exige código malicioso.
AdmBorkBork
2
Eu diria o contrário. Esse desafio pede um código que promova a privacidade e a segurança da informação.
precisa saber é o seguinte

Respostas:

1

código de máquina x86 (Linux), 116 bytes

00000000: 89cb 6a02 5931 d289 4c24 f4b0 05cd 8050  ..j.Y1..L$.....P
00000010: 5b53 6a02 5a31 c9b0 13cd 8089 c65b 5331  [Sj.Z1.......[S1
00000020: d231 c9b0 13cd 8089 f75b 53b2 018d 4c24  .1.......[S...L$
00000030: f8b0 04cd 804e 09f6 75ef 5b53 31d2 31c9  .....N..u.[S1.1.
00000040: b013 cd80 89fe 5b53 8d4c 24f4 b201 b003  ......[S.L$.....
00000050: cd80 4e09 f674 0c8a 4424 f838 4424 f474  ..N..t..D$.8D$.t
00000060: e5eb ad89 fe8a 4424 f8c6 4424 f801 3c01  ......D$..D$..<.
00000070: 759e 58c3                                u.X.

Leva o nome do arquivo como argumento

Montagem (NASM):

section .text
	global func
func:			;this function uses fastcall conventions
	;seems like no enter instr needed

	;open file
	mov ebx, ecx	;first argument to func (filename)
	push 0x2	;flag O_RDWR
	pop ecx		;pushing a constant is shorter than mov
	xor edx, 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	;using 8 bit regs is smaller
	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
	xor edx, 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 esi (byte count) to 0
		or esi, esi	;cmp esi to 0
		jne write_loop	;while esi!=0, keep looping

	;reset index of file to 0
	pop ebx		;get fd
	push ebx
	xor edx, edx	;flag 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
		or esi, esi	;cmp esi to 0 
		je end_verify	;at final byte, end verification
		mov al, [esp-8]
		cmp byte [esp-12],al
		je verify_loop	 ;keep looping if expected value found
		jmp write_verify ;if byte!=expected value, restart

	end_verify:
	mov esi, edi
	mov al, [esp-8]
	mov byte [esp-8],0x1	;set new byte to write to 1
	cmp al, 0x1
	jne write_verify	;if old byte to write!=1, goto start
	
	pop eax			;reset stack
	ret

Experimente online! (Usa um arquivo temporário)

-11 bytes, otimizando os registros móveis e usando a pilha como um buffer em vez de um local constante na memória.

Logern
fonte
3

Em um sistema Linux, não há necessidade de manipulação especial de dispositivos. Basta usar a interface do arquivo do dispositivo.

Python 3 (cadeias de bytes) - 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

É bastante direto, e não é muito otimizado, mas funciona. Aqui está um resumo básico.

  • Obter entrada (caminho do arquivo do dispositivo)
  • Abrir arquivo do dispositivo
  • Procure até o fim, obtenha o tamanho do arquivo (os dispositivos de bloco são sempre do tamanho real)
  • insira um loop de gravação e verificação
  • construir cadeias de 0 e 1 bit (x)
  • escrever bitstring
  • saída nivelada (eu poderia ter definido buffering = 0, mas isso é mais curto)
  • teste o arquivo em relação a x, e incremente a etapa do loop se ela

loop de saída quando o incremento é alto o suficiente

Como bônus, você pode modificar isso para qualquer conjunto e número de padrões de modificação de bytes, como 0x55 / 0xaa, para efeitos de substituição mais fortes.

Na verdade, testei isso em um arquivo de dispositivo, usando loopback. No entanto, não tenho 100% de certeza de que a verificação realmente funcione. Pode ser necessário fechar e reabrir o arquivo a cada passagem, devido a comportamentos de buffer. Eu espero que o flush evite isso.

* editado para incorporar algumas sugestões nos comentários

William Shipley
fonte
11
Bem vindo ao site. Você certamente não precisa de espaço em branco em torno de um =python. Você também pode reduzir sua contagem de bytes usando ;para reduzir o recuo.
Ad Hoc Garf Hunter
Normalmente, contamos envios em bytes, não caracteres. Você também f.seek(0);f.seek(0)pode usar o apelido de algumas de suas funções, por exemplo, (19 bytes) pode ser s=f.seek;s(0);s(0)(18 bytes). Além disso, if f.read()==x:i+=1pode ser i+=f.read()==x.
Jonathan Frech
Você também não deve precisar da string vazia como argumento para inserir.
Quintec 28/10
Eu acho que em b'\0'vez de b'\x00'deve funcionar.
31418 Jason
Acabei de perceber uma característica importante. Este programa consumirá RAM igual ao tamanho do dispositivo apagado.
William Shipley
2

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--);}}

Experimente online!

Leva o nome do arquivo como argumento

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++;
	}
}
Logern
fonte
Hmm ... o TiO vai limpar a internet? ;-D
Tito
@Titus Cria um arquivo temporário e o limpa.
Logern 30/10/18
1

Tcl, 286 bytes

proc f {o i l} {seek $o 0
set s [string repeat $i $l]
puts -nonewline $o $s
flush $o
seek $o 0
return [string equal [read $o $l] $s]}
set n [open $argv r+]
fconfigure $n -translation binary
seek $n 0 end
set m [tell $n]
while {![f $n "\0" $m]} {}
while {![f $n "\xff" $m]} {}

Não está realmente otimizado tão bem. Eu tentei o que pude, mas não sei muito sobre Tcl.

Salve como "f.tcl" e execute o Unix com tclsh f.tcl "your filename". Verifique se há exatamente um argumento! Eu testei isso em um arquivo simples, mas também deve funcionar em um arquivo de dispositivo.

Definir variáveis ​​e indexação está mais envolvido no Tcl, então decidi colocar o código comum entre as passagens em uma função. Então eu chamo primeiro com "\ 0" e repito enquanto ele não verifica. Eu faço a mesma coisa com "\ xff".

Eu liberado depois de escrever; pode não ser necessário. fconfigure -translation binary -buffering noneÉ mais longo.

-2 bytes removendo aspas r+.

Jason
fonte