According to the spec the shx contains a 100 byte header followed by a sequence of 8 byte records. Each record stores a 4 byte offset and a 4 byte content length for a record in the main .shp data file.
+-----------------------------------------------+
| header (100 bytes) |
+-----------------+------------------+----------+
| offset(4 bytes) | length (4 bytes) |
+-----------------+------------------+
| offset(4 bytes) | length (4 bytes) |
+-----------------+------------------+
| offset(4 bytes) | length (4 bytes) |
+-----------------+------------------+
| offset(4 bytes) | length (4 bytes) |
+-----------------+------------------+
| .... |
+-----------------+------------------+
Note that the offset is specified in 16 bit words, so the offset for the first record is 50 (as the .shp header is 100 bytes, or 50 words, long). The content length is also specified in 16 bit words.
So, you can figure out the number of records from (index_file_length-100)/8
, and use the index to access a particular shape record in the .shp file at random or in sequence.