private static string Calculate(DriveInfo drive, IEnumerable <string> fileNames) { List <FileInfo> files = fileNames.Select(fileName => new FileInfo(fileName)).ToList(); files.Sort(CompareFiles); List <byte[]> hashes = new List <byte[]>(); //Step 2: //The file headers from each file are computed in the CRC. foreach (FileInfo file in files) { AddFileMetaHash(file, hashes); } //Step 3: //The data from the VMGI file ("VIDEO_TS\VIDEO_TS.IFO") is computed in the CRC. //If present, the first 65,536 bytes of "VIDEO_TS.IFO are read and added to the CRC (if smaller then the entire file is added) AddFileContentHash(drive, "VIDEO_TS.IFO", hashes); //Note: On page 19 the patents talks about "the first VTSI file ('VIDEO_TS\VTS_xx_0.IFO')" // but on page 20 it explicitly specifies "VTS_01_0.IFO". //Step 4: //The data from the first VTSI file ("VIDEO_TS\VTS_xx_0.IFO") is computed in the CRC. string vtsFileName = GetVtsFileName(drive); //If present, the first 65,536 bytes of "VTS_01_0.IFO" are read and added to the CRC (if smaller then the entire file is added) AddFileContentHash(drive, vtsFileName, hashes); byte[] hashBytes = hashes.SelectMany(bytes => bytes).ToArray(); ulong hash = Crc64.Calculate(hashBytes); string result = hash.ToString("X").PadLeft(16, '0'); return(result); }