├── .github └── workflows │ ├── lint.yml │ └── test.yml ├── LICENSE ├── Makefile ├── README.md ├── go.mod ├── go.sum ├── magic.go ├── magic_test.go └── types.go /.github/workflows/lint.yml: -------------------------------------------------------------------------------- 1 | name: Lint 2 | on: 3 | pull_request: 4 | jobs: 5 | build: 6 | name: lint 7 | runs-on: ubuntu-latest 8 | steps: 9 | - uses: actions/checkout@v3 10 | - uses: actions/setup-go@v3 11 | with: 12 | go-version-file: go.mod 13 | cache: true 14 | cache-dependency-path: go.sum 15 | - run: make lint 16 | -------------------------------------------------------------------------------- /.github/workflows/test.yml: -------------------------------------------------------------------------------- 1 | name: Test 2 | on: 3 | pull_request: 4 | jobs: 5 | build: 6 | name: test 7 | runs-on: ubuntu-latest 8 | steps: 9 | - uses: actions/checkout@v3 10 | - uses: actions/setup-go@v3 11 | with: 12 | go-version-file: go.mod 13 | cache: true 14 | cache-dependency-path: go.sum 15 | - run: make test 16 | 17 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | This is free and unencumbered software released into the public domain. 2 | 3 | Anyone is free to copy, modify, publish, use, compile, sell, or 4 | distribute this software, either in source code form or as a compiled 5 | binary, for any purpose, commercial or non-commercial, and by any 6 | means. 7 | 8 | In jurisdictions that recognize copyright laws, the author or authors 9 | of this software dedicate any and all copyright interest in the 10 | software to the public domain. We make this dedication for the benefit 11 | of the public at large and to the detriment of our heirs and 12 | successors. We intend this dedication to be an overt act of 13 | relinquishment in perpetuity of all present and future rights to this 14 | software under copyright law. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 20 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. 23 | 24 | For more information, please refer to 25 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | golangcilint_version := "1.53.3" 2 | 3 | default : lint test 4 | 5 | .PHONY: lint 6 | lint: 7 | @echo "Linting..." 8 | @(which golangci-lint && [[ "$$(golangci-lint --version | awk '{print $$4}')" == "$(golangcilint_version)" ]] ) || go install github.com/golangci/golangci-lint/cmd/golangci-lint@v$(golangcilint_version) 9 | @golangci-lint run 10 | 11 | .PHONY: test 12 | test: 13 | go test -race ./... 14 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # magic 2 | 3 | Toolkit for detecting and verifying file type using magic bytes in pure Go 4 | 5 | Support for all file signatures listed [here](https://en.wikipedia.org/wiki/List_of_file_signatures). 6 | 7 | You only need to provide the first few hundred bytes of a given file to detect the file type, unless you want to detect `.iso` images, which require examination of the first 32774 bytes. 8 | 9 | A description and a suggested file extension are provided where relevant, and MIME types will be added in future. 10 | 11 | ## Example Usage 12 | 13 | ```go 14 | package main 15 | 16 | import "github.com/liamg/magic" 17 | 18 | func main() { 19 | 20 | data := []byte{0xa1, 0xb2, 0xc3, 0xd4, 0x00, 0x00, 0x00, 0x00} 21 | 22 | fileType, err := magic.Lookup(data) 23 | if err != nil { 24 | if err == magic.ErrUnknown { 25 | fmt.Println("File type is unknown") 26 | os.Exit(1) 27 | }else{ 28 | panic(err) 29 | } 30 | } 31 | 32 | fmt.Printf("File extension: %s\n", fileType.Extension) 33 | fmt.Printf("File type description: %s\n", fileType.Description) 34 | } 35 | ``` 36 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/liamg/magic 2 | 3 | go 1.20 4 | 5 | require ( 6 | github.com/stretchr/testify v1.8.4 7 | gotest.tools v2.2.0+incompatible 8 | ) 9 | 10 | require ( 11 | github.com/davecgh/go-spew v1.1.1 // indirect 12 | github.com/google/go-cmp v0.5.9 // indirect 13 | github.com/pkg/errors v0.9.1 // indirect 14 | github.com/pmezard/go-difflib v1.0.0 // indirect 15 | gopkg.in/yaml.v3 v3.0.1 // indirect 16 | ) 17 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 2 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 3 | github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= 4 | github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= 5 | github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= 6 | github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 7 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 8 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 9 | github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= 10 | github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= 11 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= 12 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 13 | gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= 14 | gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 15 | gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo= 16 | gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= 17 | -------------------------------------------------------------------------------- /magic.go: -------------------------------------------------------------------------------- 1 | package magic 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "runtime" 7 | ) 8 | 9 | type job struct { 10 | input []byte 11 | reference FileType 12 | resultChan chan *FileType 13 | } 14 | 15 | // LookupConfig is a struct that contains configuration details to modify the default Lookup behavior 16 | type LookupConfig struct { 17 | ConcurrencyEnabled bool // the search will be performed concurrently by multiple worker goroutines when this field is set to true. The search will be carried out by the calling goroutine if set to false. 18 | WorkerCount int // number of worker goroutines to be spawned if concurrency is set to true. If set to -1, workerCount will be set to use all the available cores. 19 | } 20 | 21 | // ErrUnknown infers the file type cannot be determined by the provided magic bytes 22 | var ErrUnknown = fmt.Errorf("unknown file type") 23 | 24 | // Lookup looks up the file type based on the provided magic bytes. You should provide at least the first 1024 bytes of the file in this slice. 25 | // A magic.ErrUnknown will be returned if the file type is not known. 26 | func Lookup(bytes []byte) (*FileType, error) { 27 | return lookup(bytes, true, -1) 28 | } 29 | 30 | // LookupWithConfig looks up the file type based on the provided magic bytes, and a given configuration. You should provide at least the first 1024 bytes of the file in this slice. 31 | // A magic.ErrUnknown will be returned if the file type is not known. 32 | func LookupWithConfig(bytes []byte, config LookupConfig) (*FileType, error) { 33 | return lookup(bytes, config.ConcurrencyEnabled, config.WorkerCount) 34 | } 35 | 36 | // LookupSync lookups up the file type based on the provided magic bytes without spawning any additional goroutines. You should provide at least the first 1024 bytes of the file in this slice. 37 | // A magic.ErrUnknown will be returned if the file type is not known. 38 | func LookupSync(bytes []byte) (*FileType, error) { 39 | return lookup(bytes, false, 0) 40 | } 41 | 42 | func lookup(bytes []byte, concurrent bool, workers int) (*FileType, error) { 43 | // additional worker count check: avoid deadlock when worker count is set to zero 44 | if !concurrent || workers == 0 { 45 | for _, t := range Types { 46 | ft := t.check(bytes, 0) 47 | if ft != nil { 48 | return ft, nil 49 | } 50 | } 51 | return nil, ErrUnknown 52 | } 53 | 54 | // use all available cores 55 | workerCount := runtime.GOMAXPROCS(0) 56 | if workers > -1 && workers < workerCount { 57 | workerCount = workers 58 | } 59 | workChan := make(chan job) 60 | resultChan := make(chan *FileType) 61 | 62 | ctx, cancel := context.WithCancel(context.Background()) 63 | defer cancel() 64 | 65 | // spawn workers 66 | for i := 0; i < workerCount; i++ { 67 | go worker(ctx, workChan) 68 | } 69 | 70 | awaiting := len(Types) 71 | 72 | // queue work 73 | go func() { 74 | for _, t := range Types { 75 | select { 76 | case <-ctx.Done(): 77 | return 78 | case workChan <- job{ 79 | input: bytes, 80 | reference: t, 81 | resultChan: resultChan, 82 | }: 83 | } 84 | } 85 | 86 | }() 87 | 88 | for { 89 | result := <-resultChan 90 | if result != nil { 91 | return result, nil 92 | } 93 | awaiting-- 94 | if awaiting <= 0 { 95 | break 96 | } 97 | } 98 | 99 | return nil, ErrUnknown 100 | } 101 | 102 | func worker(ctx context.Context, work chan job) { 103 | for { 104 | select { 105 | case <-ctx.Done(): 106 | return 107 | case job := <-work: 108 | select { 109 | case <-ctx.Done(): 110 | return 111 | case job.resultChan <- job.reference.check(job.input, job.reference.Offset): 112 | } 113 | } 114 | } 115 | } 116 | -------------------------------------------------------------------------------- /magic_test.go: -------------------------------------------------------------------------------- 1 | package magic 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/stretchr/testify/require" 7 | "gotest.tools/assert" 8 | ) 9 | 10 | func TestLookup(t *testing.T) { 11 | 12 | fileType, err := Lookup([]byte{0xa1, 0xb2, 0xc3, 0xd4, 0x00, 0x00, 0x00, 0x00}) 13 | require.Nil(t, err) 14 | 15 | assert.Equal(t, fileType.Extension, "pcap") 16 | 17 | } 18 | 19 | func TestNestedLookup(t *testing.T) { 20 | 21 | fileType, err := Lookup([]byte{0x52, 0x49, 0x46, 0x46, 0, 0, 0, 0, 0x57, 0x41, 0x56, 0x45}) 22 | require.Nil(t, err) 23 | 24 | assert.Equal(t, fileType.Extension, "wav") 25 | 26 | } 27 | 28 | func TestLookupWithConfig(t *testing.T) { 29 | payload := []byte{31, 139, 8, 0, 130, 139, 110, 100, 2, 255, 61, 143, 65, 14, 131, 32, 20, 68, 247} 30 | 31 | workerCounts := []int{-1, 0, 1, 2, 10000} 32 | 33 | lookupConfigs := func(counts []int) []LookupConfig { 34 | configs := make([]LookupConfig, len(workerCounts)*2) 35 | for i := 0; i < len(counts)*2; i++ { 36 | configs[i] = LookupConfig{ 37 | WorkerCount: counts[i%len(counts)], 38 | } 39 | if i < len(counts) { 40 | configs[i].ConcurrencyEnabled = true 41 | } 42 | } 43 | return configs 44 | }(workerCounts) 45 | 46 | for _, config := range lookupConfigs { 47 | fileType, err := LookupWithConfig(payload, config) 48 | require.Nil(t, err) 49 | assert.Equal(t, fileType.Extension, "gz") 50 | } 51 | 52 | } 53 | 54 | func TestLookupSync(t *testing.T) { 55 | 56 | fileType, err := LookupSync([]byte{0xa1, 0xb2, 0xc3, 0xd4, 0x00, 0x00, 0x00, 0x00}) 57 | require.Nil(t, err) 58 | 59 | assert.Equal(t, fileType.Extension, "pcap") 60 | 61 | } 62 | 63 | func TestNestedLookupSync(t *testing.T) { 64 | 65 | fileType, err := LookupSync([]byte{0x52, 0x49, 0x46, 0x46, 0, 0, 0, 0, 0x57, 0x41, 0x56, 0x45}) 66 | require.Nil(t, err) 67 | 68 | assert.Equal(t, fileType.Extension, "wav") 69 | } 70 | 71 | func TestLookupWithOffset(t *testing.T) { 72 | fileType, err := Lookup([]byte{0x00, 0x00, 0x00, 0x20, 0x66, 0x74, 0x79, 0x70, 0x33, 0x67, 0x97}) 73 | require.Nil(t, err) 74 | 75 | assert.Equal(t, fileType.Extension, "3gp") 76 | } 77 | -------------------------------------------------------------------------------- /types.go: -------------------------------------------------------------------------------- 1 | package magic 2 | 3 | import "bytes" 4 | 5 | // FileType provides information about the type of the file inferred from the provided magic bytes 6 | type FileType struct { 7 | Description string 8 | MIME string 9 | Extension string 10 | Magic []byte 11 | Offset int 12 | children []FileType 13 | } 14 | 15 | func (ft *FileType) check(data []byte, offset int) *FileType { 16 | if len(data) <= offset { 17 | return nil 18 | } 19 | trunc := data[offset:] 20 | if len(trunc) < len(ft.Magic) { 21 | return nil 22 | } 23 | if bytes.Equal(trunc[:len(ft.Magic)], ft.Magic) { 24 | if ft.children == nil { 25 | return ft 26 | } 27 | for _, child := range ft.children { 28 | f := child.check(trunc, child.Offset+len(ft.Magic)) 29 | if f != nil { 30 | return &child 31 | } 32 | } 33 | } 34 | 35 | return nil 36 | } 37 | 38 | /* 39 | Run on https://en.wikipedia.org/wiki/List_of_file_signatures 40 | 41 | var code = ""; 42 | $('tr', $($('table')[0])).each(function(i, e){ 43 | 44 | var offset = $($('td', $(e))[2]).text(); 45 | var ext = $($('td', $(e))[3]).text().split("\n")[0]; 46 | var desc = $($('td', $(e))[4]).text(); 47 | 48 | $('pre', $($('td', $(e))[0])).each(function(i,e){ 49 | var raw = $(e).text(); 50 | var output = "{\n"; 51 | output += "\tMagic: []byte{ 0x" + raw.trim().replace("\n", " ").split(/ /g).join(', 0x') + "},\n"; 52 | output += "\tOffset: " + offset.trim() + ",\n"; 53 | output += "\tDescription: \"" + desc.trim() + "\",\n"; 54 | output += "\tExtension: \"" + ext.trim() + "\",\n"; 55 | output += "\tMIME: \"\",\n"; 56 | output += "},\n"; 57 | code += output + "\n\n"; 58 | }); 59 | }); 60 | */ 61 | 62 | var Types = []FileType{ 63 | { 64 | Magic: []byte{0xa1, 0xb2, 0xc3, 0xd4}, 65 | Offset: 0, 66 | Description: "Libpcap File Format", 67 | Extension: "pcap", 68 | MIME: "", 69 | }, 70 | 71 | { 72 | Magic: []byte{0xd4, 0xc3, 0xb2, 0xa1}, 73 | Offset: 0, 74 | Description: "Libpcap File Format", 75 | Extension: "pcap", 76 | MIME: "", 77 | }, 78 | 79 | { 80 | Magic: []byte{0x0a, 0x0d, 0x0d, 0x0a}, 81 | Offset: 0, 82 | Description: "PCAP Next Generation Dump File Format", 83 | Extension: "pcapng", 84 | MIME: "", 85 | }, 86 | 87 | { 88 | Magic: []byte{0xed, 0xab, 0xee, 0xdb}, 89 | Offset: 0, 90 | Description: "RedHat Package Manager (RPM) package ", 91 | Extension: "rpm", 92 | MIME: "", 93 | }, 94 | 95 | { 96 | Magic: []byte{0x53, 0x51, 0x4c, 0x69, 0x74, 0x65, 0x20, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x20, 0x33, 0x00}, 97 | Offset: 0, 98 | Description: "SQLite Database ", 99 | Extension: "sqlite", 100 | MIME: "", 101 | }, 102 | 103 | { 104 | Magic: []byte{0x53, 0x50, 0x30, 0x31}, 105 | Offset: 0, 106 | Description: "Amazon Kindle Update Package ", 107 | Extension: "bin", 108 | MIME: "", 109 | }, 110 | 111 | { 112 | Magic: []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, 113 | Offset: 11, 114 | Description: "PalmPilot Database/Document File", 115 | Extension: "pdb", 116 | MIME: "", 117 | }, 118 | 119 | { 120 | Magic: []byte{0xBE, 0xBA, 0xFE, 0xCA}, 121 | Offset: 0, 122 | Description: "Palm Desktop Calendar Archive", 123 | Extension: "dba", 124 | MIME: "", 125 | }, 126 | 127 | { 128 | Magic: []byte{0x00, 0x01, 0x42, 0x44}, 129 | Offset: 0, 130 | Description: "Palm Desktop To Do Archive", 131 | Extension: "dba", 132 | MIME: "", 133 | }, 134 | 135 | { 136 | Magic: []byte{0x00, 0x01, 0x44, 0x54}, 137 | Offset: 0, 138 | Description: "Palm Desktop Calendar Archive", 139 | Extension: "tda", 140 | MIME: "", 141 | }, 142 | 143 | { 144 | Magic: []byte{0x00, 0x01, 0x00, 0x00}, 145 | Offset: 0, 146 | Description: "Palm Desktop Data File (Access format)", 147 | Extension: "pdd", 148 | MIME: "", 149 | }, 150 | 151 | { 152 | Magic: []byte{0x00, 0x00, 0x01, 0x00}, 153 | Offset: 0, 154 | Description: "Icon encoded in ICO file format", 155 | Extension: "ico", 156 | MIME: "", 157 | }, 158 | 159 | { 160 | Magic: []byte{0x66, 0x74, 0x79, 0x70, 0x33, 0x67}, 161 | Offset: 4, 162 | Description: "3rd Generation Partnership Project 3GPP and 3GPP2 multimedia files", 163 | Extension: "3gp", 164 | MIME: "", 165 | }, 166 | 167 | { 168 | Magic: []byte{0x1F, 0x9D}, 169 | Offset: 0, 170 | Description: "compressed file using Lempel-Ziv-Welch algorithm", 171 | Extension: "tar.z", 172 | MIME: "", 173 | }, 174 | 175 | { 176 | Magic: []byte{0x1F, 0xA0}, 177 | Offset: 0, 178 | Description: "Compressed file using LZH algorithm", 179 | Extension: "tar.z", 180 | MIME: "", 181 | }, 182 | 183 | { 184 | Magic: []byte{0x42, 0x41, 0x43, 0x4B, 0x4D, 0x49, 0x4B, 0x45, 0x44, 0x49, 0x53, 0x4B}, 185 | Offset: 0, 186 | Description: "File or tape containing a backup done with AmiBack on an Amiga", 187 | Extension: "bac", 188 | MIME: "", 189 | }, 190 | 191 | { 192 | Magic: []byte{0x42, 0x5A, 0x68}, 193 | Offset: 0, 194 | Description: "Compressed file using Bzip2 algorithm", 195 | Extension: "bz2", 196 | MIME: "", 197 | }, 198 | 199 | { 200 | Magic: []byte{0x47, 0x49, 0x46, 0x38, 0x37, 0x61}, 201 | Offset: 0, 202 | Description: "Image file encoded in the Graphics Interchange Format (GIF)", 203 | Extension: "gif", 204 | MIME: "", 205 | }, 206 | 207 | { 208 | Magic: []byte{0x47, 0x49, 0x46, 0x38, 0x39, 0x61}, 209 | Offset: 0, 210 | Description: "Image file encoded in the Graphics Interchange Format (GIF)", 211 | Extension: "gif", 212 | MIME: "", 213 | }, 214 | 215 | { 216 | Magic: []byte{0x49, 0x49, 0x2A, 0x00}, 217 | Offset: 0, 218 | Description: "Tagged Image File Format", 219 | Extension: "tiff", 220 | MIME: "", 221 | }, 222 | 223 | { 224 | Magic: []byte{0x4D, 0x4D, 0x00, 0x2A}, 225 | Offset: 0, 226 | Description: "Tagged Image File Format", 227 | Extension: "tiff", 228 | MIME: "", 229 | }, 230 | 231 | { 232 | Magic: []byte{0x49, 0x49, 0x2A, 0x00, 0x10, 0x00, 0x00, 0x00, 0x43, 0x52}, 233 | Offset: 0, 234 | Description: "Canon RAW Format Version 2[8]Canon's RAW format is based on the TIFF file format", 235 | Extension: "cr2", 236 | MIME: "", 237 | }, 238 | 239 | { 240 | Magic: []byte{0x80, 0x2A, 0x5F, 0xD7}, 241 | Offset: 0, 242 | Description: "Kodak Cineon image", 243 | Extension: "cin", 244 | MIME: "", 245 | }, 246 | 247 | { 248 | Magic: []byte{0x52, 0x4E, 0x43, 0x01}, 249 | Offset: 0, 250 | Description: "Compressed file using Rob Northen Compression algorithm", 251 | Extension: "", 252 | MIME: "", 253 | }, 254 | 255 | { 256 | Magic: []byte{0x52, 0x4E, 0x43, 0x02}, 257 | Offset: 0, 258 | Description: "Compressed file using Rob Northen Compression algorithm", 259 | Extension: "", 260 | MIME: "", 261 | }, 262 | 263 | { 264 | Magic: []byte{0x53, 0x44, 0x50, 0x58}, 265 | Offset: 0, 266 | Description: "SMPTE DPX image", 267 | Extension: "dpx", 268 | MIME: "", 269 | }, 270 | 271 | { 272 | Magic: []byte{0x58, 0x50, 0x44, 0x53}, 273 | Offset: 0, 274 | Description: "SMPTE DPX image", 275 | Extension: "dpx", 276 | MIME: "", 277 | }, 278 | 279 | { 280 | Magic: []byte{0x76, 0x2F, 0x31, 0x01}, 281 | Offset: 0, 282 | Description: "OpenEXR image", 283 | Extension: "exr", 284 | MIME: "", 285 | }, 286 | 287 | { 288 | Magic: []byte{0x42, 0x50, 0x47, 0xFB}, 289 | Offset: 0, 290 | Description: "Better Portable Graphics format", 291 | Extension: "bpg", 292 | MIME: "", 293 | }, 294 | 295 | { 296 | Magic: []byte{0xFF, 0xD8, 0xFF, 0xDB}, 297 | Offset: 0, 298 | Description: "JPEG raw or in the JFIF or Exif file format", 299 | Extension: "jpg", 300 | MIME: "", 301 | }, 302 | 303 | { 304 | Magic: []byte{0xFF, 0xD8, 0xFF, 0xE0, 0x00, 0x10, 0x4A, 0x46, 0x49, 0x46, 0x00, 0x01}, 305 | Offset: 0, 306 | Description: "JPEG raw or in the JFIF or Exif file format", 307 | Extension: "jpg", 308 | MIME: "", 309 | }, 310 | 311 | { 312 | Magic: []byte{0x49, 0x4E, 0x44, 0x58}, 313 | Offset: 0, 314 | Description: "Index file to a file or tape containing a backup done with AmiBack on an Amiga.", 315 | Extension: "idx", 316 | MIME: "", 317 | }, 318 | 319 | { 320 | Magic: []byte{0x4C, 0x5A, 0x49, 0x50}, 321 | Offset: 0, 322 | Description: "lzip compressed file", 323 | Extension: "lz", 324 | MIME: "", 325 | }, 326 | 327 | { 328 | Magic: []byte{0x4D, 0x5A}, 329 | Offset: 0, 330 | Description: "DOS MZ executable file format and its descendants (including NE and PE)", 331 | Extension: "exe", 332 | MIME: "", 333 | }, 334 | 335 | { 336 | Magic: []byte{0x50, 0x4B, 0x03, 0x04}, 337 | Offset: 0, 338 | Description: "zip file format and formats based on it, such as JAR, ODF, OOXML", 339 | Extension: "zip", 340 | MIME: "", 341 | }, 342 | 343 | { 344 | Magic: []byte{0x50, 0x4B, 0x05, 0x06}, 345 | Offset: 0, 346 | Description: "zip file format and formats based on it, such as JAR, ODF, OOXML", 347 | Extension: "zip", 348 | MIME: "", 349 | }, 350 | 351 | { 352 | Magic: []byte{0x50, 0x4B, 0x07, 0x08}, 353 | Offset: 0, 354 | Description: "zip file format and formats based on it, such as JAR, ODF, OOXML", 355 | Extension: "zip", 356 | MIME: "", 357 | }, 358 | 359 | { 360 | Magic: []byte{0x52, 0x61, 0x72, 0x21, 0x1A, 0x07, 0x00}, 361 | Offset: 0, 362 | Description: "RAR archive version 1.50 onwards", 363 | Extension: "rar", 364 | MIME: "", 365 | }, 366 | 367 | { 368 | Magic: []byte{0x52, 0x61, 0x72, 0x21, 0x1A, 0x07, 0x01, 0x00}, 369 | Offset: 0, 370 | Description: "RAR archive version 5.0 onwards", 371 | Extension: "rar", 372 | MIME: "", 373 | }, 374 | 375 | { 376 | Magic: []byte{0x7F, 0x45, 0x4C, 0x46}, 377 | Offset: 0, 378 | Description: "Executable and Linkable Format", 379 | Extension: "", 380 | MIME: "", 381 | }, 382 | 383 | { 384 | Magic: []byte{0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A}, 385 | Offset: 0, 386 | Description: "Image encoded in the Portable Network Graphics format", 387 | Extension: "png", 388 | MIME: "", 389 | }, 390 | 391 | { 392 | Magic: []byte{0xCA, 0xFE, 0xBA, 0xBE}, 393 | Offset: 0, 394 | Description: "Java class file, Mach-O Fat Binary", 395 | Extension: "class", 396 | MIME: "", 397 | }, 398 | 399 | { 400 | Magic: []byte{0xEF, 0xBB, 0xBF}, 401 | Offset: 0, 402 | Description: "UTF-8 encoded Unicode byte order mark, commonly seen in text files.", 403 | Extension: "", 404 | MIME: "", 405 | }, 406 | 407 | { 408 | Magic: []byte{0xFE, 0xED, 0xFA, 0xCE}, 409 | Offset: 0, 410 | Description: "Mach-O binary (32-bit)", 411 | Extension: "", 412 | MIME: "", 413 | }, 414 | 415 | { 416 | Magic: []byte{0xFE, 0xED, 0xFA, 0xCF}, 417 | Offset: 0, 418 | Description: "Mach-O binary (64-bit)", 419 | Extension: "", 420 | MIME: "", 421 | }, 422 | 423 | { 424 | Magic: []byte{0xFE, 0xED, 0xFE, 0xED}, 425 | Offset: 0, 426 | Description: "JKS JavakeyStore", 427 | Extension: "", 428 | MIME: "", 429 | }, 430 | 431 | { 432 | Magic: []byte{0xCE, 0xFA, 0xED, 0xFE}, 433 | Offset: 0, 434 | Description: "Mach-O binary (reverse byte ordering scheme, 32-bit)", 435 | Extension: "", 436 | MIME: "", 437 | }, 438 | 439 | { 440 | Magic: []byte{0xCF, 0xFA, 0xED, 0xFE}, 441 | Offset: 0, 442 | Description: "Mach-O binary (reverse byte ordering scheme, 64-bit)", 443 | Extension: "", 444 | MIME: "", 445 | }, 446 | 447 | { 448 | Magic: []byte{0xFF, 0xFE}, 449 | Offset: 0, 450 | Description: "Byte-order mark for text file encoded in little-endian 16-bit Unicode Transfer Format", 451 | Extension: "", 452 | MIME: "", 453 | }, 454 | 455 | { 456 | Magic: []byte{0xFF, 0xFE, 0x00, 0x00}, 457 | Offset: 0, 458 | Description: "Byte-order mark for text file encoded in little-endian 32-bit Unicode Transfer Format", 459 | Extension: "", 460 | MIME: "", 461 | }, 462 | 463 | { 464 | Magic: []byte{0x25, 0x21, 0x50, 0x53}, 465 | Offset: 0, 466 | Description: "PostScript document", 467 | Extension: "ps", 468 | MIME: "", 469 | }, 470 | 471 | { 472 | Magic: []byte{0x25, 0x50, 0x44, 0x46, 0x2d}, 473 | Offset: 0, 474 | Description: "PDF document", 475 | Extension: "pdf", 476 | MIME: "", 477 | }, 478 | 479 | { 480 | Magic: []byte{0x30, 0x26, 0xB2, 0x75, 0x8E, 0x66, 0xCF, 0x11, 0xA6, 0xD9, 0x00, 0xAA, 0x00, 0x62, 0xCE, 0x6C}, 481 | Offset: 0, 482 | Description: "Advanced Systems Format", 483 | Extension: "asf", 484 | MIME: "", 485 | }, 486 | 487 | { 488 | Magic: []byte{0x24, 0x53, 0x44, 0x49, 0x30, 0x30, 0x30, 0x31}, 489 | Offset: 0, 490 | Description: "System Deployment Image, a disk image format used by Microsoft", 491 | Extension: "", 492 | MIME: "", 493 | }, 494 | 495 | { 496 | Magic: []byte{0x4F, 0x67, 0x67, 0x53}, 497 | Offset: 0, 498 | Description: "Ogg, an open source media container format", 499 | Extension: "ogg", 500 | MIME: "", 501 | }, 502 | 503 | { 504 | Magic: []byte{0x38, 0x42, 0x50, 0x53}, 505 | Offset: 0, 506 | Description: "Photoshop Document file, Adobe Photoshop's native file format", 507 | Extension: "psd", 508 | MIME: "", 509 | }, 510 | 511 | { 512 | Magic: []byte{0x52, 0x49, 0x46, 0x46}, 513 | Offset: 0, 514 | children: []FileType{ 515 | { 516 | Magic: []byte{0x57, 0x41, 0x56, 0x45}, 517 | Offset: 4, 518 | Description: "Waveform Audio File Format", 519 | Extension: "wav", 520 | MIME: "", 521 | }, 522 | { 523 | Magic: []byte{0x41, 0x56, 0x49, 0x20}, 524 | Offset: 4, 525 | Description: "Audio Video Interleave video format", 526 | Extension: "avi", 527 | MIME: "", 528 | }, 529 | }, 530 | }, 531 | 532 | { 533 | Magic: []byte{0xFF, 0xFB}, 534 | Offset: 0, 535 | Description: "MPEG-1 Layer 3 file without an ID3 tag or with an ID3v1 tag (which's appended at the end of the file)", 536 | Extension: "mp3", 537 | MIME: "", 538 | }, 539 | 540 | { 541 | Magic: []byte{0x49, 0x44, 0x33}, 542 | Offset: 0, 543 | Description: "MP3 file with an ID3v2 container", 544 | Extension: "mp3", 545 | MIME: "", 546 | }, 547 | 548 | { 549 | Magic: []byte{0x42, 0x4D}, 550 | Offset: 0, 551 | Description: "BMP file, a bitmap format used mostly in the Windows world", 552 | Extension: "bmp", 553 | MIME: "", 554 | }, 555 | 556 | { 557 | Magic: []byte{0x43, 0x44, 0x30, 0x30, 0x31}, 558 | Offset: 0x8001, 559 | Description: "ISO9660 CD/DVD image file", 560 | Extension: "iso", 561 | MIME: "", 562 | }, 563 | 564 | { 565 | Magic: []byte{0x53, 0x49, 0x4D, 0x50, 0x4C, 0x45, 0x20, 0x20}, 566 | Offset: 0, 567 | Description: "Flexible Image Transport System (FITS)", 568 | Extension: "fits", 569 | MIME: "", 570 | }, 571 | 572 | { 573 | Magic: []byte{0x3D, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x54}, 574 | Offset: 0, 575 | Description: "Flexible Image Transport System (FITS)", 576 | Extension: "fits", 577 | MIME: "", 578 | }, 579 | 580 | { 581 | Magic: []byte{0x66, 0x4C, 0x61, 0x43}, 582 | Offset: 0, 583 | Description: "Free Lossless Audio Codec", 584 | Extension: "flac", 585 | MIME: "", 586 | }, 587 | 588 | { 589 | Magic: []byte{0x4D, 0x54, 0x68, 0x64}, 590 | Offset: 0, 591 | Description: "MIDI sound file", 592 | Extension: "mid", 593 | MIME: "", 594 | }, 595 | 596 | { 597 | Magic: []byte{0xD0, 0xCF, 0x11, 0xE0, 0xA1, 0xB1, 0x1A, 0xE1}, 598 | Offset: 0, 599 | Description: "Compound File Binary Format, a container format used for document by older versions of Microsoft Office.[21] It is however an open format used by other programs as well.", 600 | Extension: "doc", 601 | MIME: "", 602 | }, 603 | 604 | { 605 | Magic: []byte{0x64, 0x65, 0x78, 0x0A, 0x30, 0x33, 0x35, 0x00}, 606 | Offset: 0, 607 | Description: "Dalvik Executable", 608 | Extension: "dex", 609 | MIME: "", 610 | }, 611 | 612 | { 613 | Magic: []byte{0x4B, 0x44, 0x4D}, 614 | Offset: 0, 615 | Description: "VMDK files[22]", 616 | Extension: "vmdk", 617 | MIME: "", 618 | }, 619 | 620 | { 621 | Magic: []byte{0x43, 0x72, 0x32, 0x34}, 622 | Offset: 0, 623 | Description: "Google Chrome extension[24] or packaged app", 624 | Extension: "crx", 625 | MIME: "", 626 | }, 627 | 628 | { 629 | Magic: []byte{0x41, 0x47, 0x44, 0x33}, 630 | Offset: 0, 631 | Description: "FreeHand 8 document[26][27]", 632 | Extension: "fh8", 633 | MIME: "", 634 | }, 635 | 636 | { 637 | Magic: []byte{0x05, 0x07, 0x00, 0x00, 0x42, 0x4F, 0x42, 0x4F, 0x05, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}, 638 | Offset: 0, 639 | Description: "AppleWorks 5 document", 640 | Extension: "cwk", 641 | MIME: "", 642 | }, 643 | 644 | { 645 | Magic: []byte{0x06, 0x07, 0xE1, 0x00, 0x42, 0x4F, 0x42, 0x4F, 0x06, 0x07, 0xE1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}, 646 | Offset: 0, 647 | Description: "AppleWorks 6 document", 648 | Extension: "cwk", 649 | MIME: "", 650 | }, 651 | 652 | { 653 | Magic: []byte{0x45, 0x52, 0x02, 0x00, 0x00, 0x00}, 654 | Offset: 0, 655 | Description: "Roxio Toast disc image file, also some .dmg-files begin with same bytes", 656 | Extension: "toast", 657 | MIME: "", 658 | }, 659 | 660 | { 661 | Magic: []byte{0x8B, 0x45, 0x52, 0x02, 0x00, 0x00, 0x00}, 662 | Offset: 0, 663 | Description: "Roxio Toast disc image file, also some .dmg-files begin with same bytes", 664 | Extension: "toast", 665 | MIME: "", 666 | }, 667 | 668 | { 669 | Magic: []byte{0x78, 0x01, 0x73, 0x0D, 0x62, 0x62, 0x60}, 670 | Offset: 0, 671 | Description: "Apple Disk Image file", 672 | Extension: "dmg", 673 | MIME: "", 674 | }, 675 | 676 | { 677 | Magic: []byte{0x78, 0x61, 0x72, 0x21}, 678 | Offset: 0, 679 | Description: "eXtensible ARchive format", 680 | Extension: "xar", 681 | MIME: "", 682 | }, 683 | 684 | { 685 | Magic: []byte{0x50, 0x4D, 0x4F, 0x43, 0x43, 0x4D, 0x4F, 0x43}, 686 | Offset: 0, 687 | Description: "Windows Files And Settings Transfer Repository", 688 | Extension: "dat", 689 | MIME: "", 690 | }, 691 | 692 | { 693 | Magic: []byte{0x4E, 0x45, 0x53, 0x1A}, 694 | Offset: 0, 695 | Description: "Nintendo Entertainment System ROM file", 696 | Extension: "nes", 697 | MIME: "", 698 | }, 699 | 700 | { 701 | Magic: []byte{0x75, 0x73, 0x74, 0x61, 0x72, 0x00, 0x30, 0x30}, 702 | Offset: 0x101, 703 | Description: "tar archive", 704 | Extension: "tar", 705 | MIME: "", 706 | }, 707 | 708 | { 709 | Magic: []byte{0x75, 0x73, 0x74, 0x61, 0x72, 0x20, 0x20, 0x00}, 710 | Offset: 0x101, 711 | Description: "tar archive", 712 | Extension: "tar", 713 | MIME: "", 714 | }, 715 | 716 | { 717 | Magic: []byte{0x74, 0x6F, 0x78, 0x33}, 718 | Offset: 0, 719 | Description: "Open source portable voxel file", 720 | Extension: "tox", 721 | MIME: "", 722 | }, 723 | 724 | { 725 | Magic: []byte{0x4D, 0x4C, 0x56, 0x49}, 726 | Offset: 0, 727 | Description: "Magic Lantern Video file", 728 | Extension: "mlv", 729 | MIME: "", 730 | }, 731 | 732 | { 733 | Magic: []byte{0x44, 0x43, 0x4D, 0x01, 0x50, 0x41, 0x33, 0x30}, 734 | Offset: 0, 735 | Description: "Windows Update Binary Delta Compression", 736 | Extension: "", 737 | MIME: "", 738 | }, 739 | 740 | { 741 | Magic: []byte{0x37, 0x7A, 0xBC, 0xAF, 0x27, 0x1C}, 742 | Offset: 0, 743 | Description: "7-Zip File Format", 744 | Extension: "7z", 745 | MIME: "", 746 | }, 747 | 748 | { 749 | Magic: []byte{0x1F, 0x8B}, 750 | Offset: 0, 751 | Description: "GZIP compressed file", 752 | Extension: "gz", 753 | MIME: "", 754 | }, 755 | 756 | { 757 | Magic: []byte{0xFD, 0x37, 0x7A, 0x58, 0x5A, 0x00, 0x00}, 758 | Offset: 0, 759 | Description: "XZ compression utility using LZMA2 compression", 760 | Extension: "xz", 761 | MIME: "", 762 | }, 763 | 764 | { 765 | Magic: []byte{0x04, 0x22, 0x4D, 0x18}, 766 | Offset: 0, 767 | Description: "LZ4 Frame Format", 768 | Extension: "lz4", 769 | MIME: "", 770 | }, 771 | 772 | { 773 | Magic: []byte{0x4D, 0x53, 0x43, 0x46}, 774 | Offset: 0, 775 | Description: "Microsoft Cabinet file", 776 | Extension: "cab", 777 | MIME: "", 778 | }, 779 | 780 | { 781 | Magic: []byte{0x53, 0x5A, 0x44, 0x44, 0x88, 0xF0, 0x27, 0x33}, 782 | Offset: 0, 783 | Description: "Microsoft compressed file in Quantum format", 784 | Extension: "", 785 | MIME: "", 786 | }, 787 | 788 | { 789 | Magic: []byte{0x46, 0x4C, 0x49, 0x46}, 790 | Offset: 0, 791 | Description: "Free Lossless Image Format", 792 | Extension: "flif", 793 | MIME: "", 794 | }, 795 | 796 | { 797 | Magic: []byte{0x1A, 0x45, 0xDF, 0xA3}, 798 | Offset: 0, 799 | Description: "Matroska media container, including WebM", 800 | Extension: "webm", 801 | MIME: "", 802 | }, 803 | 804 | { 805 | Magic: []byte{0x4D, 0x49, 0x4C, 0x20}, 806 | Offset: 0, 807 | Description: "SEAN: Session Analysis Training file", 808 | Extension: "stg", 809 | MIME: "", 810 | }, 811 | 812 | { 813 | Magic: []byte{0x30, 0x82}, 814 | Offset: 0, 815 | Description: "DER encoded X.509 certificate", 816 | Extension: "der", 817 | MIME: "", 818 | }, 819 | 820 | { 821 | Magic: []byte{0x44, 0x49, 0x43, 0x4D}, 822 | Offset: 0x80, 823 | Description: "DICOM Medical File Format", 824 | Extension: "dcm", 825 | MIME: "", 826 | }, 827 | 828 | { 829 | Magic: []byte{0x77, 0x4F, 0x46, 0x46}, 830 | Offset: 0, 831 | Description: "WOFF File Format 1.0", 832 | Extension: "woff", 833 | MIME: "", 834 | }, 835 | 836 | { 837 | Magic: []byte{0x77, 0x4F, 0x46, 0x32}, 838 | Offset: 0, 839 | Description: "WOFF File Format 2.0", 840 | Extension: "woff2", 841 | MIME: "", 842 | }, 843 | 844 | { 845 | Magic: []byte{0x3c, 0x3f, 0x78, 0x6d, 0x6c, 0x20}, 846 | Offset: 0, 847 | Description: "eXtensible Markup Language when using the ASCII character encoding", 848 | Extension: "XML", 849 | MIME: "", 850 | }, 851 | 852 | { 853 | Magic: []byte{0x00, 0x61, 0x73, 0x6d}, 854 | Offset: 0, 855 | Description: "WebAssembly binary format", 856 | Extension: "wasm", 857 | MIME: "", 858 | }, 859 | 860 | { 861 | Magic: []byte{0xcf, 0x84, 0x01}, 862 | Offset: 0, 863 | Description: "Lepton compressed JPEG image", 864 | Extension: "lep", 865 | MIME: "", 866 | }, 867 | 868 | { 869 | Magic: []byte{0x43, 0x57, 0x53}, 870 | Offset: 0, 871 | Description: "flash .swf", 872 | Extension: "swf", 873 | MIME: "", 874 | }, 875 | 876 | { 877 | Magic: []byte{0x46, 0x57, 0x53}, 878 | Offset: 0, 879 | Description: "flash .swf", 880 | Extension: "swf", 881 | MIME: "", 882 | }, 883 | 884 | { 885 | Magic: []byte{0x21, 0x3C, 0x61, 0x72, 0x63, 0x68, 0x3E}, 886 | Offset: 0, 887 | Description: "linux deb file", 888 | Extension: "deb", 889 | MIME: "", 890 | }, 891 | 892 | { 893 | Magic: []byte{0x52, 0x49, 0x46, 0x46}, 894 | Offset: 0, 895 | children: []FileType{ 896 | { 897 | Magic: []byte{0x57, 0x45, 0x42, 0x50}, 898 | Offset: 4, 899 | Description: "Google WebP image file", 900 | Extension: "webp", 901 | MIME: "", 902 | }, 903 | }, 904 | }, 905 | 906 | { 907 | Magic: []byte{0x27, 0x05, 0x19, 0x56}, 908 | Offset: 0, 909 | Description: "U-Boot/uImage/Das U-Boot/Universal Boot Loader.", 910 | Extension: "", 911 | MIME: "", 912 | }, 913 | 914 | { 915 | Magic: []byte{0x7B, 0x5C, 0x72, 0x74, 0x66, 0x31}, 916 | Offset: 0, 917 | Description: "Rich Text Format", 918 | Extension: "rtf", 919 | MIME: "", 920 | }, 921 | 922 | { 923 | Magic: []byte{0x54, 0x41, 0x50, 0x45}, 924 | Offset: 0, 925 | Description: "Microsoft Tape Format", 926 | Extension: "", 927 | MIME: "", 928 | }, 929 | 930 | { 931 | Magic: []byte{0x47}, 932 | Offset: 0, 933 | Description: "MPEG Transport Stream (MPEG-2 Part 1)", 934 | Extension: "ts", 935 | MIME: "", 936 | }, 937 | 938 | { 939 | Magic: []byte{0x00, 0x00, 0x01, 0xBA}, 940 | Offset: 0, 941 | Description: "MPEG Program Stream (MPEG-1 Part 1 (essentially identical) and MPEG-2 Part 1)", 942 | Extension: "m2p", 943 | MIME: "", 944 | }, 945 | 946 | { 947 | Magic: []byte{0x00, 0x00, 0x01, 0xBA}, 948 | Offset: 0, 949 | Description: "MPEG Program Stream", 950 | Extension: "mpg", 951 | MIME: "", 952 | }, 953 | 954 | { 955 | Magic: []byte{0x47}, 956 | Offset: 0, 957 | Description: "MPEG Program Stream", 958 | Extension: "mpg", 959 | MIME: "", 960 | }, 961 | 962 | { 963 | Magic: []byte{0x00, 0x00, 0x01, 0xB3}, 964 | Offset: 0, 965 | Description: "MPEG Program Stream", 966 | Extension: "mpg", 967 | MIME: "", 968 | }, 969 | 970 | { 971 | Magic: []byte{0x78, 0x01}, 972 | Offset: 0, 973 | Description: "zlib: No/Low Compression", 974 | Extension: "zlib", 975 | MIME: "", 976 | }, 977 | 978 | { 979 | Magic: []byte{0x78, 0x9C}, 980 | Offset: 0, 981 | Description: "zlib: Default Compression", 982 | Extension: "zlib", 983 | MIME: "", 984 | }, 985 | 986 | { 987 | Magic: []byte{0x78, 0xDA}, 988 | Offset: 0, 989 | Description: "zlib: Best Compression", 990 | Extension: "zlib", 991 | MIME: "", 992 | }, 993 | 994 | { 995 | Magic: []byte{0x62, 0x76, 0x78, 0x32}, 996 | Offset: 0, 997 | Description: "LZFSE - Lempel-Ziv style data compression algorithm using Finite State Entropy coding. OSS by Apple.", 998 | Extension: "lzfse", 999 | MIME: "", 1000 | }, 1001 | 1002 | { 1003 | Magic: []byte{0x4F, 0x52, 0x43}, 1004 | Offset: 0, 1005 | Description: "Apache ORC (Optimized Row Columnar) file format", 1006 | Extension: "orc", 1007 | MIME: "", 1008 | }, 1009 | 1010 | { 1011 | Magic: []byte{0x4F, 0x62, 0x6A, 0x01}, 1012 | Offset: 0, 1013 | Description: "Apache Avro binary file format", 1014 | Extension: "avro", 1015 | MIME: "", 1016 | }, 1017 | 1018 | { 1019 | Magic: []byte{0x53, 0x45, 0x51, 0x36}, 1020 | Offset: 0, 1021 | Description: "RCFile columnar file format", 1022 | Extension: "rc", 1023 | MIME: "", 1024 | }, 1025 | 1026 | { 1027 | Magic: []byte{0x65, 0x87, 0x78, 0x56}, 1028 | Offset: 0, 1029 | Description: "PhotoCap Object Templates", 1030 | Extension: "", 1031 | MIME: "", 1032 | }, 1033 | 1034 | { 1035 | Magic: []byte{0x55, 0x55, 0xaa, 0xaa}, 1036 | Offset: 0, 1037 | Description: "PhotoCap Vector", 1038 | Extension: "pcv", 1039 | MIME: "", 1040 | }, 1041 | 1042 | { 1043 | Magic: []byte{0x78, 0x56, 0x34}, 1044 | Offset: 0, 1045 | Description: "PhotoCap Template", 1046 | Extension: "", 1047 | MIME: "", 1048 | }, 1049 | 1050 | { 1051 | Magic: []byte{0x50, 0x41, 0x52, 0x31}, 1052 | Offset: 0, 1053 | Description: "Apache Parquet columnar file format", 1054 | Extension: "", 1055 | MIME: "", 1056 | }, 1057 | 1058 | { 1059 | Magic: []byte{0x45, 0x4D, 0x58, 0x32}, 1060 | Offset: 0, 1061 | Description: "Emulator Emaxsynth samples", 1062 | Extension: "ez2", 1063 | MIME: "", 1064 | }, 1065 | 1066 | { 1067 | Magic: []byte{0x45, 0x4D, 0x55, 0x33}, 1068 | Offset: 0, 1069 | Description: "Emulator III synth samples", 1070 | Extension: "ez3", 1071 | MIME: "", 1072 | }, 1073 | 1074 | { 1075 | Magic: []byte{0x1B, 0x4C, 0x75, 0x61}, 1076 | Offset: 0, 1077 | Description: "Lua bytecode", 1078 | Extension: "luac", 1079 | MIME: "", 1080 | }, 1081 | 1082 | { 1083 | Magic: []byte{0x62, 0x6F, 0x6F, 0x6B, 0x00, 0x00, 0x00, 0x00, 0x6D, 0x61, 0x72, 0x6B, 0x00, 0x00, 0x00, 0x00}, 1084 | Offset: 0, 1085 | Description: "macOS file Alias[46] (Symbolic link)", 1086 | Extension: "alias", 1087 | MIME: "", 1088 | }, 1089 | 1090 | { 1091 | Magic: []byte{0x5B, 0x5A, 0x6F, 0x6E, 0x65, 0x54, 0x72, 0x61, 0x6E, 0x73, 0x66, 0x65, 0x72, 0x5D}, 1092 | Offset: 0, 1093 | Description: "Microsoft Zone Identifier for URL Security Zones", 1094 | Extension: "Identifier", 1095 | MIME: "", 1096 | }, 1097 | 1098 | { 1099 | Magic: []byte{0x52, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x64}, 1100 | Offset: 0, 1101 | Description: "Email Message var5", 1102 | Extension: "eml", 1103 | MIME: "", 1104 | }, 1105 | 1106 | { 1107 | Magic: []byte{0x20, 0x02, 0x01, 0x62, 0xA0, 0x1E, 0xAB, 0x07, 0x02, 0x00, 0x00, 0x00}, 1108 | Offset: 0, 1109 | Description: "Tableau Datasource", 1110 | Extension: "tde", 1111 | MIME: "", 1112 | }, 1113 | 1114 | { 1115 | Magic: []byte{0x28, 0xB5, 0x2F, 0xFD}, 1116 | Offset: 0, 1117 | Description: "Zstandard compressed file[49]", 1118 | Extension: "zst", 1119 | MIME: "", 1120 | }, 1121 | } 1122 | --------------------------------------------------------------------------------