Найкоротший код для безпечного витирання диска


9

Давайте напишемо найкоротший код для виконання спрощеного варіанту методу протирання DoD 5220.22-M лише з двома записами на запис.

Будь-яка мова програмування прийнята, але використання бібліотек, орієнтованих на витирання дисків, заборонено.

Ось як ми реалізуємо це у псевдокоді:

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

Іншими словами, цей код буде виконуватися двічі, з пропуском для запису та перевіркою для підтвердження, а також з пропуском для 0запису та перевіркою для перевірки 1.

Хто-небудь досить м'який, щоб втілити його у стилі код-гольф? ;)


6
Я сумніваюся, що це отримає будь-які відповіді через те, як важко буде перевірити.
— Джеймс

12
Серйозно, що зробив ваш SSD для того, щоб заслужити такого роду лікування? Це вбило всю вашу колекцію плюшевого ведмедика чи щось таке?
— Р. Кап

2
Дійсно хочу спробувати вирішити це ... також дуже не хочу принести в жертву мій жорсткий диск, щоб перевірити його.
— Michelfrancis Bustillos

6
Я голосую, щоб закрити це питання поза темою, оскільки ця проблема вимагає зловмисного коду.
— AdmBorkBork

2
Я б заперечував інакше. Цей виклик запитує код, що сприяє конфіденційності та безпеці інформації.
— MathuSum Mut

Відповіді:


1

машинний код x86 (Linux), 116 байт

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.

В якості аргументу береться ім'я файлу

Асамблея (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

Спробуйте в Інтернеті! (Використовує тимчасовий файл)

-11 байт шляхом оптимізації рухомих регістрів та використання стека як буфера замість постійного розташування в пам'яті.


3

У системі Linux немає необхідності в спеціальній обробці пристроїв. Просто використовуйте інтерфейс файлу пристрою.

Python 3 (рядки байтів) - 141 байт

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

Це досить просто і не дуже оптимізовано, але це працює. Ось базовий пробіг.

  • Отримати введення (шлях до файлу пристрою)
  • Відкрити файл пристрою
  • Прагніть до кінця, отримайте розмір файлів (блокові пристрої завжди мають їх реальний розмір)
  • введіть цикл запису і перевірки
  • побудувати 0-бітні та 1-бітні рядки (x)
  • написати бітстринг
  • флеш-вихід (я міг встановити буферизацію = 0, але це коротше)
  • тестовий файл проти x та крок циклу, якщо він проходить

петлю виходу, коли приріст досить високий

Як бонус, ви можете змінити це для будь-якого набору та кількості шаблонів модифікації байтів, наприклад, 0x55 / 0xaa для більш сильних ефектів перезапису.

Я фактично перевіряв це на файлі пристрою, використовуючи loopback. Проте я не на 100% впевнений, що перевірка справді працює. Можливо, потрібно буде закрити та повторно відкрити файл кожен прохід через буферизацію поведінки. Я сподіваюся, що промивання цьому заважає.

* відредаговано, щоб включити деякі пропозиції до коментарів


1
Ласкаво просимо на сайт. Вам, звичайно, не потрібен пробіл навколо =пітона. Ви також можете зменшити кількість байтів, ;зменшивши відступ.
— Ad Hoc Hunter Hunter

Зазвичай ми рахуємо подання в байтах, а не символи. Ви також f.seek(0);f.seek(0)можете встановити псевдоніми деяких своїх функцій, наприклад (19 байт) s=f.seek;s(0);s(0)(18 байт). Крім того, if f.read()==x:i+=1може бути i+=f.read()==x.
— Джонатан Фрех

Ви також не повинні мати порожній рядок як аргумент для введення.
— Квінтек

Думаю, b'\0'замість цього b'\x00'слід працювати.
— Джейсон

Щойно зрозумів важливу особливість. Ця програма буде споживати оперативну пам’ять, рівну розміру пристрою, що витирається.
— Вільям Шиплі

2

C (кланг) , -DZ=lseek(d,0+ 139 = 152 байти

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

Спробуйте в Інтернеті!

Приймає ім'я файлу як аргумент

Безголівки:

#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++;
	}
}

Хм ... чи буде TiO витерти Інтернет? ;-D
— Тіт

@Titus Створює тимчасовий файл і витирає його.
— Логерн

1

Tcl, 286 байт

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]} {}

Не дуже оптимізовано. Я спробував, що міг, але про Tcl я не знаю так багато.

Збережіть як "f.tcl" і запустіть на Unix з tclsh f.tcl "your filename". Переконайтесь, що є рівно один аргумент! Я перевірив це на звичайному файлі, але він також повинен працювати на файлі пристрою.

Встановлення змінних та індексація більше задіяні в Tcl, тому я вирішив поставити загальний код між пропусками у функцію. Потім я називаю це спочатку "\ 0", і повторюю, поки він не може перевірити. Я роблю те саме, що і з "\ xff".

Я почервонів після запису; це може не бути необхідним. fconfigure -translation binary -buffering noneдовше.

-2 байти, видаливши лапки навколо r+ .

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.