LBR Format
| Format type | Archive |
|---|---|
| Max files | 65535 |
| File Allocation Table (FAT) | Beginning |
| Filenames? | Yes, hashed |
| Metadata? | None |
| Supports compression? | No |
| Supports encryption? | No |
| Supports subdirectories? | No |
| Hidden data? | No |
| Games | Vinyl Goddess From Mars |
The LBR Format is used by Vinyl Goddess From Mars to store most of the game data.
Contents |
File format
Signature
There is no known signature for this format. One method to identify files is to read in the file entries and ensure all the offsets are within range (and perhaps increasing in value.) It is somewhat unlikely that this method would incorrectly identify a file.
Header
The header begins at the start of the file (offset 0.)
| Data type | Description |
|---|---|
| UINT16LE numFiles | Number of files stored within |
File entry
After the header, the following structure is repeated once for each file.
| Data type | Description |
|---|---|
| UINT16LE hash | Hash of the filename |
| UINT32LE offset | Offset into LBR where file data begins |
Each file's data starts at the offset indicated. File sizes must be calculated by comparing adjacent offsets, or in the case of the last file, comparing its offset to the total size of the LBR.
Filename hash
Rather than storing filenames, LBR files store a hash calculated from the original filename. If you have a filename it is very easy to calculate the hash, but because hashes are one-way functions, if all you have is a hash it is impossible to calculate the filename (this is because each hash matches at least 56 billion different filenames. Malvineous wrote a tool to list all possible filenames for a hash matching a given prefix and suffix, but the many thousands of names produced makes this a very tedious and error-prone way of discovering filenames.)
Some example code to calculate the hashes follows.
int calcHash(const std::string& data) { int hash = 0; for (std::string::const_iterator i = data.begin(); i != data.end(); i++) { hash ^= *i << 8; for (int j = 0; j < 8; j++) { hash <<= 1; if (hash & 0x10000) hash ^= 0x1021; } } return hash & 0xffff; }
Vgfmext also contains BASIC code to calculate hashes, using a slight variation.
Tools
The following tools are able to work with files in this format.
| Name | Platform | Extract files? | Decompress on extract? | Create new? | Modify? | Compress on insert? | Access hidden data? | Edit metadata? |
|---|---|---|---|---|---|---|---|---|
| Camoto | ? | Yes | N/A | Yes | Yes | N/A | N/A | N/A |
| Vgfmext | ? | Yes | N/A | No | No | N/A | N/A | N/A |
Credits
This file format was reverse engineered by Frenkel Smeijers with the hash algorithm refined by Malvineous. If you find this information helpful in a project you're working on, please give credit where credit is due. (A link back to this wiki would be nice too!)