-
Notifications
You must be signed in to change notification settings - Fork 1
/
README.txt
116 lines (104 loc) · 7.96 KB
/
README.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
nekofs: create and extract nekodata files
Usage: nekofs ((-x|--extract NEKOFILE) [OUTDIR] [-v|--verify] |
(-c|--create SRCDIR) [OUTFILE] | (-m|--meta FILEPATH))
Available options:
-x,--extract NEKOFILE The .nekodata file to extract
OUTDIR The output directory (default: "output")
-v,--verify verify integrity after extraction
-c,--create SRCDIR Source directory to be packed into a .nekodata file
OUTFILE The output file name (default: "SRCDIR.nekodata")
-m,--meta FILEPATH Generate "files.meta" for this directory or file
-h,--help Show this help text
Additionally, use the shell auto-completion script:
$ source <(nekofs --bash-completion-script `which nekofs`)
which also analogously applies to zsh and fish
--------------------------------------------------------------------
As my understand, the nekodata file is structured like this:
┌────────────────────────────────────────────────┐
│ │
│ Header (length = 25) │
│ │
│ Magic ('pixelneko filesystem') │
│ Word32 (0x00000000) │
│ Word8 (0x01), unknown usage │
│ │
├────────────────────────────────────────────────┤
│ │
│ File #0 │
│ │
│ ┌──────────────────────────────────────┐ │
│ │ │ │
│ │ Raw LZ4 Data Block #0 (without FD) │ │
│ │ │ │
│ ├──────────────────────────────────────┤ │
│ │ │ │
│ │ Raw LZ4 Data Block #1 │ │
│ │ │ │
│ ├──────────────────────────────────────┤ │
│ │ │ │
│ │ ... │ │
│ │ │ │
│ └──────────────────────────────────────┘ │
│ │
├────────────────────────────────────────────────┤
│ │
│ File #1 │
│ │
├────────────────────────────────────────────────┤
│ │
│ ... │
│ │
├────────────────────────────────────────────────┤
│ │
│ Metadata (encrypted with ChaCha20 cipher) │
│ │
│ Entry Count :: ShiftedVLQ │
│ │
│ ┌──────────────────────────────────────────┐ │
│ │ │ │
│ │ Entry #0 │ │
│ │ │ │
│ │ Filename Length :: ShiftedVLQ │ │
│ │ Filename :: String │ │
│ │ Word8 (0x02), unknown usage │ │
│ │ File Size :: ShiftedVLQ │ │
│ │ Total BlockSize :: ShiftedVLQ │ │
│ │ CRC32 :: IntVLQ │ │
│ │ Offset of first Block :: IntVLQ │ │
│ │ Block Counts :: ShiftedVLQ │ │
│ │ │ │
│ │ ┌────────────────────────────────────┐ │ │
│ │ │ │ │ │
│ │ │ Block Info #0 (always 0,0) │ │ │
│ │ │ │ │ │
│ │ │ Offset from 1st block │ │ │
│ │ │ :: ShiftedVLQ │ │ │
│ │ │ Offset in the original file │ │ │
│ │ │ :: ShiftedVLQ │ │ │
│ │ │ │ │ │
│ │ ├────────────────────────────────────┤ │ │
│ │ │ │ │ │
│ │ │ Block Info #1 (_, 32768*1) │ │ │
│ │ │ │ │ │
│ │ ├────────────────────────────────────┤ │ │
│ │ │ │ │ │
│ │ │ ... │ │ │
│ │ │ │ │ │
│ │ └────────────────────────────────────┘ │ │
│ │ │ │
│ ├──────────────────────────────────────────┤ │
│ │ │ │
│ │ Entry #1 │ │
│ │ │ │
│ ├──────────────────────────────────────────┤ │
│ │ │ │
│ │ ... │ │
│ │ │ │
│ └──────────────────────────────────────────┘ │
│ │
├────────────────────────────────────────────────┤
│ │
│ Length of Metadata :: ShiftedVLQ (reversed) │
│ │
└────────────────────────────────────────────────┘
where the VLQ stands for Variable Length Quantity (little-endian), and the ShiftedVLQ means the original value is rotated left by 1 before being turned into a VLQ.