Giải mã mục nhập thư mục Microsoft MS-DOS 5.0 FAT


27

Hệ thống tệp Microsoft FAT có bảng thư mục để thể hiện "tệp" nào trong đó "thư mục" trên đĩa. Hiện tại, các mục này nhồi nhét rất nhiều thông tin vào một lượng nhỏ bit. Có rất nhiều thông số kỹ thuật trên Wiki cho người tò mò, nhưng thách thức ở đây là tập trung vào giải mã "đơn giản" của một mục.

Mỗi mục bao gồm một từ nhị phân 32 byte, được chia thành nhiều phần. Để thống nhất trong thử thách này, chúng tôi sẽ sử dụng phiên bản MS-DOS 5.0, các byte được đặt hàng là endian lớn và chúng tôi gọi byte 0x00là cực trái và byte 0x1Flà cực phải.

Dưới đây là một sơ đồ ngắn gọn của các phần có liên quan, và những gì nên là đầu ra cho mỗi phần ( in đậm ).

  • 11 byte đầu tiên là tên tệp ở định dạng ASCII (đây là tên tệp 8.3 nổi tiếng đến từ - 8 byte cho tên tệp, 3 byte cho phần mở rộng). Đây là các mã hóa ASCII thẳng và nên được xuất thành ASCII với khoảng thời gian (.) Giữa .
    • Lưu ý: cả 8 và 3 phần đều được đệm bằng khoảng trắng để tạo một mục nhập có độ dài đầy đủ. Đầu ra nên bỏ qua khoảng trắng (nghĩa là không xuất chúng).
    • Phần mở rộng tệp có thể trống (nghĩa là tất cả các khoảng trắng), trong trường hợp đó, đầu ra không được xuất dấu chấm .
    • Vì ASCII chỉ sử dụng 7 bit thấp hơn, nên tất cả các byte sẽ dẫn đầu 0.
  • Byte tiếp theo (0x0b) là một bitmask sau:
    • 0x01 Chỉ đọc - đầu ra RO
    • 0x02 Ẩn - đầu ra H
    • Hệ thống 0x04 - đầu ra S
    • Nhãn khối lượng 0x08 - đầu ra VL . Kích thước tệp (bên dưới) phải là đầu ra là 0 , bất kể mục nhập thực tế của nó.
    • Thư mục con 0x10 - đầu ra SD . Kích thước tệp (bên dưới) phải là đầu ra là 0 , bất kể mục nhập thực tế của nó.
    • Lưu trữ 0x20 - đầu ra A
    • Thiết bị 0x40 - bỏ qua cho thử thách này.
    • 0x80 Dành riêng - bỏ qua cho thử thách này.
    • Vì đây là bitmask, nên có thể có nhiều cờ - tất cả các kết quả đầu ra có thể được nối với nhau theo bất kỳ thứ tự nào. Ví dụ, 0xffcó thể là ROHSVLSDA(hoặc bất kỳ sự kết hợp nào khác).
  • Hai byte tiếp theo (0x0c và 0x0d) không được sử dụng trong MS-DOS 5.0.
  • Hai byte tiếp theo (0x0e và 0x0f) là thời gian tạo như sau:
    • Các bit 15 đến 11 là các giờ ở định dạng 24 giờ - đầu ra 00 đến 23
    • Các bit 10 đến 5 là phút - đầu ra 00 đến 59
    • Các bit 4 đến 0 là giây / 2 - đầu ra 00 đến 58 (lưu ý rằng giây chỉ ở độ phân giải hai giây)
    • Để làm rõ: hhhhhmmmmmmssssskhi viết big-endian.
  • Hai byte tiếp theo (0x10 và 0x11) là ngày tạo như sau:
    • Bit 15 đến 9 là năm - sản lượng 1980 cho 0tới 2107 cho127
    • Các bit 8 đến 5 là các tháng - đầu ra 1 đến 12 (có hoặc không có số 0 đứng đầu)
    • Các bit 4 đến 0 là ngày - đầu ra 0 đến 31 (có hoặc không có số 0 đứng đầu)
    • Để làm rõ: yyyyyyymmmmdddddkhi viết big-endian.
  • Hai byte tiếp theo (0x12 và 0x13) là ngày truy cập cuối cùng. Mặc dù được sử dụng trong MS-DOS 5.0, chúng tôi bỏ qua phần này cho thử thách này.
  • Hai byte tiếp theo (0x14 và 0x15) không được MS-DOS 5.0 sử dụng.
  • Hai byte tiếp theo (0x16 và 0x17) là lần sửa đổi cuối cùng, theo cùng định dạng với thời gian tạo, ở trên.
  • Hai byte tiếp theo (0x18 và 0x19) là ngày sửa đổi cuối cùng, theo cùng định dạng với ngày tạo, ở trên.
  • Hai byte tiếp theo (0x1a và 0x1b) là vị trí cụm của tệp trên đĩa. Chúng tôi đang bỏ qua phần này cho thử thách này.
  • Bốn byte cuối cùng (0x1c, 0x1d, 0x1e và 0x1f) là kích thước tệp - đầu ra dưới dạng một số nguyên không dấu , trừ khi các cờ VL hoặc SD được đặt (ở trên), trong trường hợp này là đầu ra 0.

Đại diện trực quan

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

Đầu vào

  • Một từ 32 byte đơn (nghĩa là 256 bit), ở bất kỳ định dạng nào đều thuận tiện.
    • Đây có thể là một chuỗi 10, như một số ints không dấu , một mảng các giá trị Boolean, v.v.
    • Vui lòng xác định trong câu trả lời của bạn định dạng bạn đang sử dụng cho đầu vào.
    • Bạn không thể lấy nhiều đầu vào (nghĩa là một mảng được chia trước thành các kích thước byte có liên quan) trừ khi đó là cách duy nhất để ngôn ngữ của bạn lấy đầu vào. Phân tích cú pháp đầu vào là một phần của thách thức.
  • Bạn có thể cho rằng đầu vào là hợp lệ (ví dụ: bạn không cần thực hiện kiểm tra ngày để xác minh rằng ngày đó là hợp lệ).
  • Byte không được sử dụng có thể là tất cả 0, tất cả 1, v.v., miễn là chúng có mặt. Trong các ví dụ dưới đây, tôi đã sử dụng tất cả 0cho các byte không sử dụng.

Đầu ra

Hoặc được in ra màn hình hoặc trả lại, như sau:

  • Tên tệp dưới dạng chuỗi ASCII
  • Các thuộc tính tệp dưới dạng chuỗi ASCII
  • Thời gian tạo và ngày tạo, với các dấu phân cách thích hợp (dấu hai chấm, dấu gạch chéo, một cái gì đó để phân biệt các thành phần)
  • Thời gian sửa đổi và ngày sửa đổi, một lần nữa với các dấu phân cách thích hợp
  • Kích thước tập tin

Đầu ra có thể là một chuỗi đơn được phân tách bằng dấu cách hoặc dòng mới, các phần tử riêng biệt trong một mảng, v.v. Vui lòng chỉ định trong câu trả lời của bạn cách định dạng đầu ra của bạn.

Quy tắc

  • Các định dạng I / O tiêu chuẩn được chấp nhận.
  • Một chương trình đầy đủ hoặc một chức năng được chấp nhận.
  • Sơ hở tiêu chuẩn bị cấm.
  • Đây là , vì vậy tất cả các quy tắc chơi gôn thông thường đều được áp dụng và mã ngắn nhất sẽ thắng.
  • Tích hợp thực hiện chính xác chức năng này đều bị cấm.

Ví dụ

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

Có ổn không nếu có khoảng trắng thừa xung quanh cờ? Ví dụ, sẽ SD Slà một bộ cờ hợp lệ?
Morgan Thrapp

@MorganThrapp Chắc chắn, điều đó sẽ ổn thôi.
admBorkBork

Vì tò mò, bạn có nhận được nhiều kinh nghiệm tương tác với MS-DOS 5.0 trong một ngày không, hay bạn chỉ thực sự buồn chán trên Wikipedia một ngày?
mèo

3
@cat Một số cả hai. Tôi đã rất quan tâm đến máy tính từ khi tôi khoảng 5 tuổi và đã nhận được một chiếc máy bay hàng hóa VIC-20. Một trong những dự án khoa học máy tính cấp độ của tôi khoảng 10 năm trước là xây dựng hệ thống tập tin của riêng chúng tôi, vì vậy tôi đã nghiên cứu rất nhiều cho việc đó. Đối với điều này, tôi đã kéo một bó từ Wiki và so sánh nó với một cái gì đó có thể là một thách thức.
admBorkBork

Câu trả lời:


6

Verilog, 513 670 617 byte

Chạy bằng IVerilog. Không có cờ biên dịch đặc biệt cần thiết.

Đây là một con quái vật của các định nghĩa lồng nhau, vặn vẹo bit và sự khó chịu của việc phải lật thứ tự bit do tính thời sự (nếu không thì chuỗi không in hoặc thứ tự bit số bị sai). Đầu vào được lấy thông qua icổng, đây là cách thông thường để đưa đầu vào vào mô-đun Verilog. $displayđược sử dụng để in ra tiêu chuẩn. 6 byte có thể được lưu nếu các số 0 đứng đầu không cần thiết cho dấu thời gian.

`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

Bản giới thiệu

Testbench (Không ghi điểm):

`timescale 1ns / 1ps

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

endmodule

Chạy ví dụ:

$ 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

5

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

Đã lưu 19 byte nhờ Cᴏɴᴏʀ O'Bʀɪᴇɴ nhắc nhở tôi rằng tôi có thể gán các hàm cho một chữ cái.

Đã lưu 6 byte nhờ đề xuất của FryAmTheEggman để dọn sạch bộ lọc bitmask.

Đã lưu 21 byte nhờ câu trả lời Ruby tuyệt vời của W0lf buộc tôi phải đánh golf thêm một số thứ nữa. ;)

Đây là một con quái vật tuyệt đối. Khá chắc chắn rằng tôi có thể cắt giảm thêm một chút nữa, nhưng nó đang tiến gần đến việc bị đánh gôn.

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

có lẽ bạn có thể gán intcho một char? hoặc có thể thực hiện một chức năng thực hiện str int.
Conor O'Brien

@ CᴏɴᴏʀO'Bʀɪᴇɴ Ý kiến ​​hay!
Morgan Thrapp

Không gian giữa or 'SD'có thể được xóa, tôi nghĩ
Conor O'Brien

@ CᴏɴᴏʀO'Bʀɪᴇɴ Yup, chỉ cần làm điều đó.
Morgan Thrapp

Ồ Khá ngắn hơn một chút so với tôi dự kiến ​​câu trả lời.
admBorkBork

4

Haskell, 781 710 byte

Cảm ơn BlackCap vì đã đơn giản hóa

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

Điều này cũng cho phép rác (như một ký tự dòng mới) xuất hiện sau đầu vào.


Có cho bạn một số trái cây treo thấp: pastebin.com/X69jH75f
BlackCap

3

Java, 1721 1587 1573 1560 1511 byte:

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

Đưa đầu vào theo định dạng của chuỗi nhị phân 32 byte. Đầu ra ở định dạng của một chuỗi phân tách không gian. Đây có thể là một câu trả lời rất dài, nhưng tôi vẫn không thất vọng. Tôi rất vui vì tôi đã có thể thực hiện điều này trong Java. Mặc dù vậy, tôi vẫn sẽ cố gắng chơi golf nhiều nhất có thể.

Dùng thử trực tuyến! (Ý)


1
+1 vì sử dụng Java cho các vấn đề cấp thấp thật mỉa mai (giống như Haskell của tôi)
Fox

2

Ruby, 344 byte

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))]*' '

Phiên bản dễ đọc hơn một chút có sẵn ở đây .

Kiểm tra trực tuyến: http://ideone.com/Fww1Rw


1
Đẹp quá Có vẻ như tôi cần phải đánh golf thêm 27 byte. ;)
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]

Ít chơi gôn

(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
  ]

Kiểm tra

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>


Ok, vì vậy tôi chỉ chạy cái này trong Safari và có Script error.. Nhưng vì một số lý do trong Firefox, nó dường như hoạt động hoàn hảo. Tôi tự hỏi tại sao ...
R. Kap

@ R.Kap có lẽ Safari tương thích ES6 ít hơn Firefox. kangax.github.io/compat-table/es6
edc65

2

PHP ,301 288 byte

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];

Hãy thử trực tuyến!

Đầu vào là một chuỗi từ 32 byte thông qua STDIN, đầu ra STDOUT.

-13 byte như một chương trình độc lập.


2

Stax , 111 byte

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

Chạy và gỡ lỗi nó


Rất tiếc, lỗi của tôi. Tôi sẽ sửa chữa.
đệ quy

1
Bây giờ nó hoạt động chính xác với chi phí 3 byte.
đệ quy

1

Perl, 249 byte

Mất 32 byte làm đầu vào, đầu ra được phân tách bằng các dòng mới. unpacklà hoàn hảo cho loại phân tích cấu trúc nhị phân này.

($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

Một số điểm nổi bật:

  • Những điều đã nói ở trên unpack.
  • Toán tử rùa @{[]}cho phép nội suy mã trong một chuỗi. Nó thực sự tạo ra một tham chiếu mảng mà sau đó được bỏ qua.
  • "$str1"x!!$str2là một cách hay để $str1chỉ trả về nếu $str2là một chuỗi không trống.

Dưới đây là phiên bản hoạt động trên các mục nhập thư mục thực, với các trường cuối nhỏ và chỉ bỏ qua phần đệm bên phải trên tên tệp và phần mở rộng (vì vậy, ví dụ: " ppcg"không xóa khoảng trắng ban đầu) (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
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.