Musicbrainz DiscID calculation - kremio/audio-remote GitHub Wiki
See https://musicbrainz.org/doc/Disc_ID_Calculation
Example
cdrecord dev=/dev/cdrom -toc
CD TOC from track: 1 lba: 0 ( 0) 00:02:00 adr: 1 control: 0 mode: -1
track: 2 lba: 17848 ( 71392) 03:59:73 adr: 1 control: 0 mode: -1
track: 3 lba: 30969 ( 123876) 06:54:69 adr: 1 control: 0 mode: -1
track: 4 lba: 46655 ( 186620) 10:24:05 adr: 1 control: 0 mode: -1
track: 5 lba: 60616 ( 242464) 13:30:16 adr: 1 control: 0 mode: -1
track: 6 lba: 76295 ( 305180) 16:59:20 adr: 1 control: 0 mode: -1
track: 7 lba: 87619 ( 350476) 19:30:19 adr: 1 control: 0 mode: -1
track: 8 lba: 104349 ( 417396) 23:13:24 adr: 1 control: 0 mode: -1
track: 9 lba: 125591 ( 502364) 27:56:41 adr: 1 control: 0 mode: -1
track: 10 lba: 139249 ( 556996) 30:58:49 adr: 1 control: 0 mode: -1
track: 11 lba: 152466 ( 609864) 33:54:66 adr: 1 control: 0 mode: -1
track: 12 lba: 167994 ( 671976) 37:21:69 adr: 1 control: 0 mode: -1
track: 13 lba: 184911 ( 739644) 41:07:36 adr: 1 control: 0 mode: -1
track: 14 lba: 203205 ( 812820) 45:11:30 adr: 1 control: 0 mode: -1
track: 15 lba: 218117 ( 872468) 48:30:17 adr: 1 control: 0 mode: -1
track: 16 lba: 231713 ( 926852) 51:31:38 adr: 1 control: 0 mode: -1
track: 17 lba: 250625 ( 1002500) 55:43:50 adr: 1 control: 0 mode: -1
track: 18 lba: 269158 ( 1076632) 59:50:58 adr: 1 control: 0 mode: -1
track: 19 lba: 283271 ( 1133084) 62:58:71 adr: 1 control: 0 mode: -1
track: 20 lba: 298959 ( 1195836) 66:28:09 adr: 1 control: 0 mode: -1
track:lout lba: 334253 ( 1337012) 74:18:53 adr: 1 control: 0 mode: -1
Expected DiscID
d_M.p37bVcYyqGi94zO5XzDVe7w-
cd-discid --musicbrainz
Output from 20 150 17998 31119 46805 60766 76445 87769 104499 125741 139399 152616 168144 185061 203355 218267 231863 250775 269308 283421 299109 334403
This is how these numbers relate to the content of the TOC given by cdrecord:
- #1: The number of tracks
- #2 to #21: LBA offset for each track + 150 to account for the lead-in track standard size of 150 logical blocks
- #22: Lead-out track LBA offset + 150
Computing the DiscID with Node
This reference snippet shows exactly how to calculate the DiscID based on the TOC given in the example
// All the audio track LBA offsets
var toc = "150 17998 31119 46805 60766 76445 87769 104499 125741 139399 152616 168144 185061 203355 218267 231863 250775 269308 283421 299109".split(" ").map( (d) => Number(d) )
// Fill the array with 0s to reach 99 tracks
while(toc.length < 99){ toc.push(0) }
// Add the lead-oud track LBA offset in front of the array
toc.unshift( 334403 )
// Convert TOC into hexadecimal uppercase ASCII format
var bin = toc.reduce( (acc,d) => {
acc.push(Number(d).toString(16).padStart(8,0).toUpperCase())
return acc
}, [
Number(1).toString(16).padStart(2,0).toUpperCase(), //First track number
Number(20).toString(16).padStart(2,0).toUpperCase() //Last track number
] )
// Create SHA-1 digest object
const crypto = require('crypto')
let hash = crypto.createHash('sha1')
// Update the hash
bin.forEach( (d) => hash.update(d,'ascii') )
// Get the buffer holding the SHA-1 digest data
let digest = hash.digest()
// BASE64 encode formula for Musicbrainz
let discId = digest.toString('base64') // Get its BASE64 representation: 'd/M+p37bVcYyqGi94zO5XzDVe7w='
.replace('+','.').replace('/','_').replace('=','-') // convert +, /, and = to respectively ., _, and -
// --> 'd_M.p37bVcYyqGi94zO5XzDVe7w-', nailed it!