liveBook · Manning

Magic number

As explained in Learn Haskell by Example

A magic number is a distinctive value in a file header that identifies the file format and sometimes its encoding variant.

A magic number is a distinctive header value that identifies what kind of file is being read and, in some formats, which encoding variant it uses. Read it from the file contents rather than relying on the extension: PNM headers use it to distinguish PBM, PGM, and PPM images and their ASCII or binary forms; other signatures can categorize files such as images or compressed data. section 12.1.1 section 14.2

For PNM, the header is always ASCII, even when pixel data is binary. P1 and P4 denote bitmaps, P2 and P5 graymaps, and P3 and P6 pixmaps. The number also determines the expected pixel layout: one value for bitmap or grayscale pixels, and three RGB values for a pixmap pixel. section 12.1.1

Table 12.1 Overview of the magic numbers for the PNM formats
Format
Magic numbers
Extension
Image data (for one pixel)
ASCII
Binary
Portable bitmap format (PBM)
P1
P4
.pbm
0 (white) or 1 (black)
Portable graymap format (PGM)
P2
P5
.pgm
From 0 to maximum value (grayscale), where the maximum value is given in the header
Portable pixmap format (PPM)
P3
P6
.ppm
From 0 to maximum value for each RGB channel, where the maximum value is given in the header

Compare the six PNM markers with their extensions, encodings, and per-pixel data before writing a parser or validator. section 12.1.1

Use a magic number as the first decision in a file-reading pipeline:

  • Read only the prefix needed to recognize supported signatures; ByteString handle reads can stop safely at EOF. section 14.2
  • Parse a recognized marker into a domain value such as MagicNumber instead of leaving it as raw text. section 12.1.2
  • Retain unconsumed input so later parsers can read dimensions, maximum values, and pixel data. section 12.1.2
  • Validate the later data against the marker: pixel count, pixel shape, maximum value, and image category must agree. section 13.2

Parsing a PNM marker

Represent P1 through P6 with a MagicNumber sum type. A fixed-string parser can map "P1" to P1 and leave " 100 100" for subsequent header parsing; an unrecognized prefix returns an error instead of crashing. Once a marker is known, header parsing can skip maximum-value parsing for P1 and P4, but require it for the other PNM variants. section 12.1.2 section 12.1.5

Recognizing generic file signatures

A file-type action can read up to eight bytes, unpack the prefix, and pattern-match hexadecimal signatures. For example, BMP begins 42 4d, PNG begins 89 50 4e 47 0d 0a 1a 0a, JPEG begins ff d8 ff, bzip2 begins 42 5a 68, and gzip begins 1f 8b. Map recognized signatures to categories such as Image or Compressed; classify all others as Other. section 14.2

How Learn Haskell by Example covers it

How deep it goes
Builds parsers from fixed-string matching through remainder-carrying composition and branches header parsing on previously read markers.
Examples
Demonstrates PBM and PGM headers, P1–P6 parser cases, and byte signatures for BMP, PNG, JPEG, bzip2, and gzip.
What it assumes
Assumes basic Haskell types and introduces magic-number parsing with Text, Either errors, and a custom Parser type.
What you can do after
Apply it via Data.ByteString and Haskell parsers to recognize supported file formats and reject inconsistent PNM data.
How it connects
Connects magic numbers with PNM headers, parser combinators, Either errors, ByteString, file handles, and validation.

Also explained in

Compare how 2 books explain magic number →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Learn Haskell by Example. The section links point to the parts of the book it draws on.