Dekodieren Sie einen Microsoft MS-DOS 5.0 FAT-Verzeichniseintrag

27

Das Microsoft FAT-Dateisystem verfügt über eine Verzeichnistabelle, die angibt, welche "Dateien" sich in welchen "Ordnern" auf der Festplatte befinden. Für die Zeit haben diese Einträge viele Informationen in eine kleine Menge von Bits gepackt. Es gibt eine Reihe von technischen Spezifikationen im Wiki für Neugierige, aber die Herausforderung hier wird sich auf eine "einfache" Dekodierung eines Eintrags konzentrieren.

Jeder Eintrag besteht aus einem 32-Byte-Binärwort, das in mehrere Abschnitte unterteilt ist. Aus Konsistenzgründen verwenden wir die MS-DOS 5.0-Version, die Bytes sind als Big Endian geordnet und wir nennen Byte ganz 0x00links und Byte ganz 0x1Frechts.

Nachfolgend finden Sie eine kurze schematische Darstellung der relevanten Abschnitte und die Ausgabe für jeden Abschnitt (in Fettdruck ).

  • Die ersten 11 Bytes sind der Dateiname im ASCII-Format (hierher kommt der berühmte 8.3-Dateiname - 8 Bytes für den Dateinamen, 3 Bytes für die Erweiterung). Dies ist eine reine ASCII-Codierung und sollte als ASCII mit einem Punkt (.) Dazwischen ausgegeben werden .
    • Hinweis: Sowohl die 8- als auch die 3-Teile sind mit Leerzeichen aufgefüllt, um eine Eingabe in voller Länge zu ermöglichen. Die Ausgabe sollte Leerzeichen ignorieren (dh nicht ausgeben).
    • Die Dateierweiterung kann leer sein (dh alle Leerzeichen). In diesem Fall sollte die Ausgabe nicht den Punkt ausgeben .
    • Da ASCII nur die unteren 7 Bits verwendet, werden die Bytes alle vorangestellt 0.
  • Das nächste Byte (0x0b) ist eine Bitmaske der folgenden Art:
    • 0x01 Read Only - RO ausgeben
    • 0x02 Hidden - Ausgabe von H
    • 0x04 System - Ausgang S
    • 0x08 Volume Label - Ausgabe VL . Die Dateigröße (unten) sollte unabhängig von ihrem tatsächlichen Eintrag als 0 ausgegeben werden .
    • 0x10-Unterverzeichnis - SD ausgeben . Die Dateigröße (unten) sollte unabhängig von ihrem tatsächlichen Eintrag als 0 ausgegeben werden .
    • 0x20 Archiv - Ausgabe A
    • 0x40 Gerät - für diese Herausforderung ignoriert.
    • 0x80 Reserviert - für diese Herausforderung ignoriert.
    • Da dies eine Bitmaske ist, sind mehrere Flags möglich - alle zutreffenden Ausgaben sollten in beliebiger Reihenfolge miteinander verkettet werden. Zum Beispiel 0xffkönnte es sein ROHSVLSDA(oder irgendeine andere Kombination).
  • Die nächsten zwei Bytes (0x0c und 0x0d) werden unter MS-DOS 5.0 nicht verwandt.
  • Die nächsten zwei Bytes (0x0e und 0x0f) sind die Erstellungszeit wie folgt:
    • Die Bits 15 bis 11 sind die Stunden im 24-Stunden-Format - Ausgabe 00 bis 23
    • Die Bits 10 bis 5 sind die Minuten - Ausgabe 00 bis 59
    • Die Bits 4 bis 0 sind die Sekunden / 2 - Ausgabe von 00 bis 58 (beachten Sie, dass die Sekunden nur eine Auflösung von zwei Sekunden haben).
    • Zur Verdeutlichung: hhhhhmmmmmmssssswenn Big-Endian geschrieben.
  • Die nächsten zwei Bytes (0x10 und 0x11) sind das Erstellungsdatum wie folgt:
    • Die Bits 15 bis 9 geben die Jahresausgabe 1980 für 0bis zu 2107 für an127
    • Bits 8 bis 5 sind die Monate - Ausgabe 1 bis 12 (mit oder ohne führende Null)
    • Bits 4 bis 0 sind der Tag - Ausgabe 0 bis 31 (mit oder ohne führende Null)
    • Zur Verdeutlichung: yyyyyyymmmmdddddwenn Big-Endian geschrieben.
  • Die nächsten zwei Bytes (0x12 und 0x13) sind das letzte Zugriffsdatum. Wir ignorieren diesen Teil für diese Herausforderung, während wir in MS-DOS 5.0 verwandt werden.
  • Die nächsten zwei Bytes (0x14 und 0x15) werden von MS-DOS 5.0 nicht verwandt.
  • Die nächsten zwei Bytes (0x16 und 0x17) sind die letzte geänderte Zeit und folgen demselben Format wie die oben angegebene Erstellungszeit.
  • Die nächsten zwei Bytes (0x18 und 0x19) sind das letzte Änderungsdatum und folgen demselben Format wie das Erstellungsdatum oben.
  • Die nächsten zwei Bytes (0x1a und 0x1b) sind der Cluster-Speicherort der Datei auf der Festplatte. Wir ignorieren diesen Teil für diese Herausforderung.
  • Die letzten vier Bytes (0x1c, 0x1d, 0x1e und 0x1f) stellen die Dateigröße dar - werden als Ganzzahl ohne Vorzeichen ausgegeben , sofern nicht die VL- oder SD- Flags gesetzt sind ( siehe oben). In diesem Fall wird ausgegeben 0.

Visuelle Darstellung

0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
\______________________________FILENAME________________________________________________/\_ATTR_/\___NOTUSED____/\_CREATIONTIME_/\_CREATIONDATE_/\__LASTACCESS__/\___NOTUSED____/\_MODIFIEDTIME_/\_MODIFIEDDATE_/\___NOTUSED____/\___________FILESIZE___________/

Eingang

  • Ein einzelnes 32-Byte-Wort (dh 256 Bit) in einem beliebigen Format.
    • Dies kann eine Zeichenfolge von 1und 0, wie mehrere vorzeichenlose int, ein Array von Booleschen Werten usw. sein.
    • Bitte geben Sie in Ihrer Antwort an, welches Format Sie für die Eingabe verwenden.
    • Sie können nicht mehrere Eingaben vornehmen (dh ein Array, das in die relevanten Byte-Größen unterteilt ist), es sei denn, dies ist die einzige Möglichkeit für Ihre Sprache, Eingaben vorzunehmen. Das Parsen der Eingabe ist Teil der Herausforderung.
  • Sie können davon ausgehen, dass die Eingabe gültig ist (zum Beispiel müssen Sie keine Datumsprüfung durchführen, um zu überprüfen, ob das Datum gültig ist).
  • Nicht verwendete Bytes können alle 0, alle 1usw. sein, solange sie vorhanden sind. In den folgenden Beispielen habe ich all 0für die nicht verwendeten Bytes verwendet.

Ausgabe

Entweder gedruckt auf dem Bildschirm oder zurückgegeben:

  • Der Dateiname als ASCII-Zeichenfolge
  • Die Dateiattribute als ASCII-Zeichenfolge
  • Die Erstellungszeit und das Erstellungsdatum, mit entsprechenden Trennzeichen (Doppelpunkte, Schrägstriche, etwas zur Unterscheidung der Komponenten)
  • Die geänderte Uhrzeit und das geänderte Datum, ebenfalls mit entsprechenden Trennzeichen
  • Die Dateigröße

Bei der Ausgabe kann es sich um eine durch Leerzeichen oder Zeilenumbrüche getrennte Einzelzeichenfolge, separate Elemente in einem Array usw. handeln. Bitte geben Sie in Ihrer Antwort an, wie Ihre Ausgabe formatiert ist.

Regeln

  • Standard-E / A-Formate sind zulässig.
  • Es ist entweder ein vollständiges Programm oder eine Funktion zulässig.
  • Standardlücken sind verboten.
  • Dies ist , daher gelten alle üblichen Golfregeln und der kürzeste Code gewinnt.
  • Built-Ins, die genau diese Funktion ausführen, sind verboten.

Beispiele

0111000001110010011011110110011101110010011000010110110101101101011010010110111001100111000001100000000000000000101000100100010001001000110101000000000000000000000000000000000010100010010001000100100011010100000000000000000000000000000000001101000000000000

programm.ing HS 20:18:08 2016/06/20 20:18:08 2016/06/20 53248

0010000000100000001000000010000001110000011100000110001101100111001000000010000000100000000101000000000000000000010111010110110000111101100111110000000000000000000000000000000010100010010001000100100011010100000000000000000011110000000100111111001011100001

ppcg SDS 11:43:24 2010/12/31 20:18:08 2016/06/20 0
AdmBorkBork
quelle
Ist es in Ordnung, wenn die Flaggen ein Leerzeichen enthalten? Wäre zB SD Sein gültiges Flag gesetzt?
Morgan Thrapp
@ MorganThrapp Sicher, das sollte in Ordnung sein.
AdmBorkBork
Haben Sie neugierig viel Erfahrung mit der Interaktion mit MS-DOS 5.0 gesammelt, oder haben Sie sich eines Tages bei Wikipedia nur wirklich gelangweilt?
Katze
3
@cat Einige von beiden. Ich habe mich seit meinem fünften Lebensjahr stark für Computer interessiert und einen Commodore VIC-20 erhalten. Eines meiner Computerwissenschaftsprojekte vor ungefähr 10 Jahren war es, ein eigenes Dateisystem aufzubauen. Ich habe viel dafür recherchiert. Dafür habe ich ein paar aus dem Wiki genommen und es auf etwas reduziert, das eine Herausforderung sein könnte.
AdmBorkBork

Antworten:

6

Verilog, 513 670 617 Bytes

Läuft mit IVerilog. Es werden keine speziellen Kompilierungsflags benötigt.

Dies ist ein Monster aus verschachtelten Definitionen, Bit-Twiddling und dem Ärger, dass die Bitreihenfolge aufgrund der Endianness umgedreht werden muss (andernfalls wird die Zeichenfolge entweder nicht gedruckt oder die Zahlenbitreihenfolge ist falsch). Die Eingabe erfolgt über den iPort. Dies ist die übliche Art der Eingabe in ein Verilog-Modul. $displaywird zum Drucken nach Standard verwendet. 6 Bytes könnten gespeichert werden, wenn für den Zeitstempel keine führenden Nullen erforderlich wären.

`define r(o,b)wire[3:0]o;assign o={i[b],i[b+1],i[b+2],i[b+3]}; 
`define R(t,a,b,c,d,s)`r(a,s)`r(b,s+4)`r(c,s+8)`r(d,s+12)wire[15:0]t;assign t={a,b,c,d};
`define p(m,k)i[90+m]?"k":"",
`define F(a,b)"a a a b\t b%d"
module f(input[0:255]i);`R(d,q,w,e,r,112)`R(D,Q,W,E,R,128)`R(s,z,x,c,v,224)`R(S,Z,X,C,V,240)`R(p,t,y,u,o,176)`R (A,b,n,m,l,192)always@(i)$display(`F(%s%s%s,%02d:%02d:%02d%d/%d/%d),i[0:63],i[64:87]=="   "?" ":".",i[64:87],`p(5,RO)`p(4,H)`p(3,S)`p(2,VL)`p(1,SD)`p(0,A)d[15:11],d[10:5],d[4:0]*2,D[15:9]+1980,D[8:5],D[4:0],p[15:11],p[10:5],p[4:0]*2,A[15:9]+1980,A[8:5],A[4:0],|i[91:92]?0:{s,S});endmodule

Demo

Testbench (nicht bewertet):

`timescale 1ns / 1ps

module ftest;
reg [0:255] i;
f uut (
.i(i)
);
initial begin
    i=256'b0111000001110010011011110110011101110010011000010110110101101101011010010110111001100111000001100000000000000000101000100100010001001000110101000000000000000000000000000000000010100010010001000100100011010100000000000000000000000000000000001101000000000000;
    #100;
i=256'b0010000000100000001000000010000001110000011100000110001101100111001000000010000000100000000101000000000000000000010111010110110000111101100111110000000000000000000000000000000010100010010001000100100011010100000000000000000011110000000100111111001011100001;     
end

endmodule

Beispiellauf:

$ iverilog design.sv testbench.sv  && vvp a.out  
programm.ing   HS      20:18:08       2016/ 6/20      53248
    ppcg        S  SD  11:43:24       2010/12/31          0
ζ--
quelle
5

Python, 485, 479, 442, 438, 431, 429, 418, 402, 395, 391 , 370 Bytes.

Dank Cᴏɴᴏʀ O'Bʀɪᴇɴ, der mich daran erinnerte, dass ich einem Buchstaben Funktionen zuweisen kann, wurden 19 Byte gespeichert.

Dank des Vorschlags von FryAmTheEggman, den Bitmaskenfilter zu bereinigen, wurden 6 Byte eingespart.

21 Bytes gespart, dank W0lfs fantastischer Ruby-Antwort, die mich dazu zwingt, noch ein bisschen Golf zu spielen. ;)

Dies ist ein absolutes Monster. Ich bin mir ziemlich sicher, dass ich es noch ein bisschen kürzen kann, aber es wird fast so, als würde ich Golf spielen.

a=input()
j=''.join
n=lambda v:int(v,2)
f=j('RO H S VL SD A'.split()[i]for i in range(6)if n(a[88:96])&2**i)
print(j(chr(n(a[x:x+8])).strip()+'.'*(x==56)for x in range(0,88,8)).strip('.'),f,j('%02d:%02d:%02d'%(n(a[b-11:b-6]),n(a[b-6:b]),n(a[b:b+6]))+' %d/%d/%d '%(n(a[b+6:b+12])+1980,n(a[b+12:b+16]),n(a[b+16:b+21]))for b in[123,187]),n(a[208:])*(1-('V'in f or'D'in f)))
Morgan Thrapp
quelle
vielleicht könntest du inteinen char zuweisen ? oder vielleicht machen Sie eine Funktion, die durchführt str int.
Conor O'Brien
@ CᴏɴᴏʀO'Bʀɪᴇɴ Gute Idee!
Morgan Thrapp
Der Raum zwischen or 'SD'kann entfernt werden, denke ich
Conor O'Brien
@ CᴏɴᴏʀO'Bʀɪᴇɴ Yup, hab das einfach gemacht.
Morgan Thrapp
Wow. Ziemlich viel kürzer als ich erwartet hatte.
AdmBorkBork
4

Haskell, 781710 Bytes

Vielen Dank an BlackCap für die Vereinfachung

w n=('0'<$[1..2-length a])++a where a=show n
x s=tail.foldr(\a b->s:a++b)""
t=snd.span(==' ')
y a|all(==' ')a=""|0<1='.':t a
nm=(\(a,b)->t a++y b).splitAt 8
ms n(r,s)|n`mod`2^(r+1)`div`2^r>0=s|0<1=""
tm n=x ':'[w$n`div`2^11,w$n`mod`2^11`div`32,w$2*n`mod`64]
dt n=x '/'[w$1980+n`div`2^9,w$n`mod`2^9`div`32,w$n`mod`32]
pa s=x ' '[nm.map(toEnum.v.take 8).takeWhile(not.null)$iterate(drop 8)a,t,dt$v i,tm$v g,dt$v o,tm$v m,show u,"\n"]where{z n=splitAt(8*n);(a,b)=z 11 s;(c,d)=z 1 b;(e,f)=z 2 d;(g,h)=z 2 f;(i,j)=z 2 h;(k,l)=z 4 j;(m,n)=z 2 l;(o,p)=z 2 n;(q,r)=z 2 p;t=(zip [0..](words"RO H S VL SD A")>>=).ms$v c;u|any(`elem`t)"LD"=0|0<1=v r;v=foldl((+).(2*))0.map(read.pure).filter(`elem`"01")}
main=interact pa

Dies ermöglicht zusätzlich, dass nach der Eingabe Müll (wie ein Newline-Zeichen) erscheint.

Fuchs
quelle
Haben Sie Sie etwas niedrig hängenden Früchte: pastebin.com/X69jH75f
BlackCap
3

Java, 1721 1587 1573 1560 1511 Bytes:

import java.util.*;class A{int Q(String a,int b){return Integer.parseInt(a,b);}String P(int a){return Integer.toString(a);}ArrayList<String>B=new ArrayList<String>();void J(String O){B.add(O);}String TD(String l,String p,int a,int c,int d){String X,Y,Z;X=Y=Z=new String();int i=0;for(char F:l.toCharArray()){if(i<a){X+=F;}if(a<=i&i<c){Y+=F;}if(c<=i){Z+=F;}i++;}String[]H=new String[3];H[0]=P(d+Q(X,2));H[1]=P(Q(Y,2));H[2]=(p==":")?P(Q(Z,2)*2):P(Q(Z,2));int T=0;for(String A:H){H[T]=(A.length()<2)?"0"+A:A;T++;}return H[0]+p+H[1]+p+H[2];}String D(String i){String K=new String();int L=0;for(char Y:i.toCharArray()){if(L%8<1){K+=" ";}K+=Y;L++;}String[]C=K.split(" ");String[]z={"RO","H","S","VL","SD","A"};int[]l={1,2,4,8,16,32};Map<Integer,String>U=new HashMap<Integer,String>();for (int e=0;e<l.length;e++){U.put(l[e],z[e]);}String[]N={":","/",":","/"};int[]M={15,17,23,25};int[]O={5,7,5,7};int[]P={0,1980,0,1980};for(int y=1;y<9;y++){if((char)Q(C[y],2)!=' '){J(Character.toString((char)Q(C[y],2)));}}for(int v=9;v<12;v++){if((char)Q(C[v],2)!=' '){if(!B.contains(".")){J(".");}J(Character.toString((char)Q(C[v],2)));}}J(" ");int T=(char)Q(C[12],2);while(T>0){int H=l[0];for(int V:l){if(V<=T){H=V;}}J(U.get(H));T-=H;}for(int w=0;w<4;w++){J(" ");J(TD(C[M[w]]+C[M[w]+1],N[w],O[w],11,P[w]));}J(" ");if(B.contains("SD")||B.contains("VL")){J("0");}else{J(P(Q(C[29]+C[30]+C[31]+C[32],2)));}return String.join("",B);}public static void main(String[]a){A H=new A();System.out.print(H.D(new Scanner(System.in).next()));}}

Übernimmt Eingaben im Format einer 32-Byte-Binärzeichenfolge. Ausgaben im Format einer durch Leerzeichen getrennten Zeichenfolge. Dies kann eine sehr sein sehr lange Antwort, aber ich bin noch nicht enttäuscht. Ich bin nur froh, dass ich dies in Java implementieren konnte. Ich werde trotzdem versuchen, so viel wie möglich Golf zu spielen.

Probieren Sie es online! (Ideone)

R. Kap
quelle
1
+1, weil die Verwendung von Java für Low-Level-Probleme angenehm ironisch ist (ähnlich wie mein Haskell)
Fox
2

Ruby, 344 Bytes

m=gets
s=->b,l{b.slice!(0,l).to_i 2}
t=->b{'%02d:%02d:%02d %d/%d/%d'%[s[b,5],s[b,6],2*s[b,5],s[b,7]+1980,s[b,4],s[b,5],]}
i=(0..q=32).map{|i|m[i*8,8].to_i 2}
c=i.map(&:chr).join
n=c[0,8].strip
e=c[8,3].strip
e>?!&&n<<?.+e
f=''
6.times{|j|i[11][j]>0&&f<<%w(RO H S VL SD A)[j]}
$><<[n,f,t[m[112,q]],t[m[176,q]],(f[/VL|SD/]?0:m[-q,q].to_i(2))]*' '

Die etwas besser lesbare Version finden Sie hier .

Online-Test: http://ideone.com/Fww1Rw

Cristian Lupascu
quelle
1
Schön! Sieht so aus, als müsste ich noch 27 Bytes abwerfen. ;)
Morgan Thrapp
2

JavaScript (ES6), 369

(b,Z=n=>n>9?n:'0'+n,W=n=>s[n]<<8|s[n+1],U=n=>[Z((t=W(n))>>11)+`:${Z(t>>5&63)}:`+Z(t%32*2),((t=W(n+2))>>9)+1980+`/${t>>5&15}/`+t%32],X=l=>String.fromCharCode(...s.slice(p,p+=l)).trim(),s=b.match(/.{8}/g).map(x=>+('0b'+x)),p=0)=>[X(8)+((x=X(3))?'.'+x:x),[...b].map((b,i)=>'A,SD,VL,S,H,RO'.split`,`[z=(2*z|b)%4294967296,i*b-90]||'',z=0).join``,U(14),U(22),b[92]|b[91]?0:z]

Weniger golfen

(b,
  Z=n=>n>9?n:'0'+n, // zero pad
  W=n=>s[n]<<8|s[n+1], // get word
  U=n=>[
   Z((t=W(n))>>11)+`:${Z((t>>5&63)}:`+Z(t%32*2),  // decode time
   ((t=W(n+2))>>9)+1980+`/${t>>5&15}/`+t%32 // decode date
  ],
  X=l=>String.fromCharCode(...s.slice(p,p+=l)).trim(), // extract space padded string
  s=b.match(/.{8}/g).map(x=>+('0b'+x)), // convert bits to bytes
  p=0
)=>
  [ X(8)+((x=X(3))?'.'+x:x),
    [...b].map((b,i)=>'A,SD,VL,S,H,RO'.split`,`[i*b-90]||'').join``,
    [...b].slice(-32).map((b,i)=>z=2*z|b,z=0), // this line merged with the preceding one in the golfed code
    U(14),U(22),
    b[92]|b[91]?0:z
  ]

Prüfung

f=(b,Z=n=>n>9?n:'0'+n,W=n=>s[n]<<8|s[n+1],U=n=>[Z((t=W(n))>>11)+`:${Z(t>>5&63)}:`+Z(t%32*2),((t=W(n+2))>>9)+1980+`/${t>>5&15}/`+t%32],X=l=>String.fromCharCode(...s.slice(p,p+=l)).trim(),s=b.match(/.{8}/g).map(x=>+('0b'+x)),p=0)=>[X(8)+((x=X(3))?'.'+x:x),[...b].map((b,i)=>'A,SD,VL,S,H,RO'.split`,`[z=(2*z|b)%4294967296,i*b-90]||'',z=0).join``,U(14),U(22),b[92]|b[91]?0:z]

O.textContent+='\n'+f('0111000001110010011011110110011101110010011000010110110101101101011010010110111001100111000001100000000000000000101000100100010001001000110101000000000000000000000000000000000010100010010001000100100011010100000000000000000000000000000000001101000000000000')
O.textContent+='\n'+f('0010000000100000001000000010000001110000011100000110001101100111001000000010000000100000000101000000000000000000010111010110110000111101100111110000000000000000000000000000000010100010010001000100100011010100000000000000000011110000000100111111001011100001')
<pre id=O></pre>

edc65
quelle
Ok, also habe ich das gerade in Safari ausgeführt und bekam Script error.. Aber aus irgendeinem Grund scheint es in Firefox perfekt zu funktionieren. Ich frage mich, warum ...
R. Kap
@ R.Kap Safari ist wahrscheinlich weniger ES6-kompatibel als Firefox. kangax.github.io/compat-table/es6
edc65
2

PHP ,301 288 Bytes

for($b=unpack('A8f/A3e/Cl/n/Nc/N/Nm/n/Ns',$argn);$i<8;$f.=1<<$i++&$b[l]?[RO,H,S,VL,SD,A][$i-1]:'');echo trim($b[f].'.'.$b[e],' .')," $f ",($e=function($a){echo date('H:i:s Y/m/d ',mktime($a>>27&31,$a>>21&63,$a>>15&62,$a>>5&15,$a&31,1980+($a>>9&127)));})($b[c]),$e($b[m]),$b[l]&24?0:$b[s];

Probieren Sie es online!

Die Eingabe ist eine 32-Byte-Wortfolge über STDIN, die an ausgegeben wird STDOUT.

-13 Bytes als eigenständiges Programm.

640 KB
quelle
2

Stax , 111 Bytes

¼ΘUßU'ïMo^ø¬├▓> I¬i⌠·╥.↕¥½ßqS,=frT`d_`&&↓⌠ÉûÆiü=┌-< │∟Φ☼⌐¢3²Bu╜lJ╛§≥╪║ε┐╓ù♫╨Z░╖!¥É:╬Çß═╤às8Q←φ,ºï◘≥Ä£}èΦ╡FÉçø¶É

Führen Sie es aus und debuggen Sie es

rekursiv
quelle
Ups, mein Fehler. Ich werde eine Lösung finden.
rekursiver
1
Es funktioniert jetzt auf Kosten von 3 Bytes korrekt.
rekursiver
1

Perl, 249 Bytes

Nimmt 32 Bytes als Eingabe, Ausgabe wird durch Zeilenumbrüche getrennt. unpackist perfekt für diese Art der Analyse von Binärstrukturen.

($f,$e,$a,$C,$M,$s)=unpack"A8A3CxxNx4Nx2N",<>;$f=~s/ //g;$e=~s/ //g;printf"%s
@{[map+(RO,H,S,VL,SD,A)[$a&1<<$_?$_:9],0..5]}
"."%02d:%02d:%02d %d/%d/%d
"x2 .$s*!($a&24),$f.".$e"x!!$e,map{$_>>27,$_>>21&63,$_>>15&62,$_/512%128+1980,$_>>5&15,$_&31}$C,$M

Einige Höhepunkte:

  • Das vorgenannte unpack.
  • Der Turtle-Operator @{[]}ermöglicht das Interpolieren von Code in einer Zeichenfolge. Tatsächlich wird eine Arrayreferenz erstellt, die dann dereferenziert wird.
  • "$str1"x!!$str2ist eine gute Möglichkeit, $str1nur zurückzugeben, wenn $str2es sich um eine nicht leere Zeichenfolge handelt.

Unten finden Sie eine Version, die mit echten Verzeichniseinträgen mit Little-Endian-Feldern funktioniert und nur das richtige Auffüllen des Dateinamens und der Erweiterung ignoriert (z. B. " ppcg"werden die anfänglichen Leerzeichen nicht entfernt) (254 Byte).

($f,$e,$a,$C,$M,$s)=unpack"A8A3CxxVx4Vx2V",<>;$f=~s/ +$//;$e=~s/ +$//;printf"%s
@{[map+(RO,H,S,VL,SD,A)[$a&1<<$_?$_:9],0..5]}
"."%02d:%02d:%02d %d/%d/%d
"x2 .$s*!($a&24),$f.".$e"x!!$e,map{$_>>11&31,$_>>5&63,2*$_&63,($_>>25)+1980,$_>>21&15,$_>>16&31}$C,$M
Ninjalj
quelle