รหัสที่สั้นที่สุดเพื่อความปลอดภัยในการเช็ดดิสก์


9

ลองเขียนโค้ดที่สั้นที่สุดเพื่อดำเนินการตัวแปรแบบง่ายของDoD 5220.22-M Wipe Methodด้วยการเขียนเพียงสองครั้ง

ภาษาการเขียนโปรแกรมใด ๆ ที่ยอมรับ แต่การใช้งานไลบรารี่ที่มุ่งเน้นดิสก์เป็นสิ่งต้องห้าม

นี่คือวิธีที่เราจะนำไปใช้ใน pseudocode:

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

ในคำอื่น ๆ รหัสนี้จะทำงานเป็นครั้งที่สองที่มีการส่งผ่านการเขียนและผ่านการตรวจสอบสำหรับการและการเขียนผ่านและการตรวจสอบผ่านสำหรับ01

ทุกคนชื่นชอบพอที่จะใช้มันในรูปแบบของโค้ดกอล์ฟหรือไม่? ;)


6
ฉันสงสัยว่ามันจะได้รับคำตอบใด ๆ เพราะมันยากที่จะทดสอบ
James

12
จริงจัง SSD ของคุณทำอะไรกับคุณเพื่อรับการบำบัดประเภทนี้ มันฆ่าคอลเล็คชั่นตุ๊กตาหมีทั้งหมดของคุณหรือเปล่า?
R. Kap

2
ต้องการลองใช้งานจริง ๆ ... ยังไม่ต้องการเสียสละ HDD ของฉันเพื่อทดสอบ
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)
  • เขียน bitstring
  • ล้างข้อมูลเอาต์พุต (ฉันสามารถตั้งค่าบัฟเฟอร์ = 0 ได้ แต่จะสั้นกว่านี้)
  • ทดสอบไฟล์กับ x และเพิ่มขั้นตอนของลูปถ้ามันผ่าน

ออกจากลูปเมื่อการเพิ่มขึ้นจะสูงพอ

เป็นโบนัสคุณสามารถแก้ไขสิ่งนี้สำหรับชุดและจำนวนของรูปแบบการปรับเปลี่ยนไบต์เช่น 0x55 / 0xaa สำหรับเอฟเฟกต์การเขียนทับที่แข็งแกร่งขึ้น

จริง ๆ แล้วฉันทดสอบสิ่งนี้ในไฟล์อุปกรณ์โดยใช้ลูปแบ็ค อย่างไรก็ตามฉันไม่แน่ใจ 100% ว่าการตรวจสอบใช้งานได้จริง อาจจำเป็นต้องปิดและเปิดไฟล์แต่ละรอบใหม่เนื่องจากพฤติกรรมการบัฟเฟอร์ ฉันหวังว่าจะลบล้างสิ่งนี้

* แก้ไขเพื่อรวมคำแนะนำในความคิดเห็น


1
ยินดีต้อนรับสู่เว็บไซต์ แน่นอนคุณไม่ต้องการช่องว่างรอบ ๆ=ในหลาม คุณสามารถลดจำนวนไบต์ของคุณโดยใช้;เพื่อลดการเยื้อง
Ad Hoc Garf 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
Jonathan Frech

นอกจากนี้คุณไม่ควรต้องการสตริงที่ว่างเปล่าเป็นอาร์กิวเมนต์ในการป้อนข้อมูล
Quintec

ฉันคิดว่าb'\0'แทนที่จะb'\x00'ทำงานได้
Jason

เพิ่งรู้ว่าเป็นคุณสมบัติที่สำคัญ โปรแกรมนี้จะกินแรมเท่ากับขนาดของอุปกรณ์ที่เช็ด
William Shipley

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

ลองออนไลน์!

ใช้ชื่อไฟล์เป็นอาร์กิวเมนต์

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

อืม ... TiO จะล้างอินเทอร์เน็ตหรือไม่ ;-D
Titus

@Titus มันสร้างไฟล์ชั่วคราวและเช็ดมัน
Logern

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" tclsh f.tcl "your filename"และทำงานบนระบบปฏิบัติการยูนิกซ์กับ ตรวจสอบให้แน่ใจว่ามีอาร์กิวเมนต์เดียวทั้งหมด! ฉันทดสอบสิ่งนี้ในไฟล์ธรรมดา แต่ควรใช้กับไฟล์อุปกรณ์ได้เช่นกัน

การตั้งค่าตัวแปรและการทำดัชนีมีส่วนร่วมใน Tcl มากขึ้นดังนั้นฉันจึงตัดสินใจใส่รหัสทั่วไประหว่างการส่งผ่านเข้าไปในฟังก์ชัน จากนั้นฉันจะเรียกมันด้วย "\ 0" ก่อนแล้วค่อยทำซ้ำในขณะที่ไม่สามารถยืนยันได้ ฉันทำสิ่งเดียวกันกับ "\ xff"

ฉันล้างหลังจากเขียน; มันอาจไม่จำเป็น fconfigure -translation binary -buffering noneอีกต่อไป

-2 r+ไบต์โดยการเอาคำพูดรอบ

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.