2 * rcracki_mt is a multithreaded implementation and fork of the original
5 * Copyright 2010 Martin Westergaard Jørgensen <martinwj2005@gmail.com>
6 * Copyright 2010 Daniël Niggebrugge <niggebrugge@fox-it.com>
7 * Copyright 2010 James Nobis <frt@quelrod.net>
9 * This file is part of rcracki_mt.
11 * rcracki_mt is free software: you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation, either version 2 of the License, or
14 * (at your option) any later version.
16 * rcracki_mt is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with rcracki_mt. If not, see <http://www.gnu.org/licenses/>.
25 #include "RTI2Reader.h"
29 RTI2Header *RTI2Reader::m_pHeader = NULL;
30 RTI2Reader::RTI2Reader(string Filename)
32 //m_pIndexPos = NULL, m_pChainPos = NULL;;
34 m_pFile = fopen(Filename.c_str(), "rb");
37 printf("Unable to open file %s", Filename.c_str());
40 FILE *pFileIndex = fopen(Filename.append(".index").c_str(), "rb");
41 if(pFileIndex == NULL)
43 printf("Unable to open file %s", Filename.append(".index").c_str());
48 long len = GetFileLen(pFileIndex);
49 fseek(pFileIndex, 0, SEEK_SET);
51 m_pIndex = new (nothrow) unsigned char[len];
52 if(m_pIndex == NULL) {
53 printf("Error allocating %ld MB memory for index in RTI2Reader::RTI2Reader()", len / (1024 * 1024));
56 if(fread(m_pIndex, 1, len, pFileIndex) != (unsigned long)len)
58 printf("Error while reading index file");
62 m_pHeader = new RTI2Header();
63 memcpy(m_pHeader, m_pIndex, sizeof(RTI2Header));
64 m_pHeader->m_cppos = (unsigned int*)(m_pIndex + 8);
65 m_pHeader->prefixstart = *(uint64*)(m_pIndex + 8 + (m_pHeader->rti_cplength * 4));
66 m_chainsizebytes = (uint32)ceil((float)(m_pHeader->rti_startptlength + m_pHeader->rti_endptlength + m_pHeader->rti_cplength) / 8); // Get the size of each chain in bytes
67 m_indexrowsizebytes = (uint32)ceil((float)m_pHeader->rti_index_numchainslength / 8);
69 fseek(m_pFile, 0, SEEK_END);
71 fseek(m_pFile, 0, SEEK_SET);
72 if(len % m_chainsizebytes > 0)
74 printf("Invalid filesize %ld\n", len);
81 RTI2Reader::~RTI2Reader(void)
83 if(m_pIndex != NULL) delete m_pIndex;
84 if(m_pFile != NULL) fclose(m_pFile);
88 unsigned int RTI2Reader::GetChainsLeft()
90 long len = GetFileLen(m_pFile);
91 return len / m_chainsizebytes - m_chainPosition;
94 int RTI2Reader::ReadChains(unsigned int &numChains, RainbowChainO *pData)
96 if(strncmp(m_pHeader->header, "RTI2", 4) != 0)
101 unsigned char *pNumChains = m_pIndex + (m_pHeader->rti_cplength * 4) + 16; // Pointer into the index containing info about how many numbers are in the first chain prefix
103 unsigned int indexRow = 0; // Current offset into the index
104 unsigned int curRowPosition = 0;
106 while(true) // Fast forward to current position
108 // ALERT: Possible problem here if m_indexrowsizebytes > 1 as pNumChains is a unsigned char.
109 unsigned int NumChainsInRow = (unsigned int)*(pNumChains + indexRow * m_indexrowsizebytes);
110 if(m_indexrowsizebytes > 1)
112 //XXX Have to find a solution to this problem
113 printf( "FATAL: m_indexrowsizebytes > 1: %d\n", m_indexrowsizebytes );
116 if(i + NumChainsInRow > m_chainPosition)
118 curRowPosition = m_chainPosition - i;
119 break; // The current position is somewhere within this prefix
125 uint64 chainrow = 0; // Buffer to store a single read chain
126 unsigned int chainsProcessed = 0; // Number of chains processed
128 // XXX: same problem with unsigned char here.
129 unsigned int NumChainsInRow = *(pNumChains + indexRow);
130 while(chainsProcessed < numChains && fread(&chainrow, 1, m_chainsizebytes, m_pFile) == m_chainsizebytes)
132 if(curRowPosition >= NumChainsInRow)
133 { // Skip to next index row position
136 NumChainsInRow = *(pNumChains + indexRow);
138 while(NumChainsInRow == 0) // We skip forward until we hit a index with > 0 chains
141 NumChainsInRow = *(pNumChains + indexRow);
144 // Load the starting point from the data
145 pData[chainsProcessed].nIndexS = chainrow << ( 64 - m_pHeader->rti_startptlength );
146 pData[chainsProcessed].nIndexS = pData[chainsProcessed].nIndexS >> ( 64 - m_pHeader->rti_startptlength );
148 // Load the ending point prefix
149 pData[chainsProcessed].nIndexE = ( m_pHeader->prefixstart + indexRow ) << m_pHeader->rti_endptlength;
150 // Append the ending point suffix
151 #if defined(_WIN32) && !defined(__GNUC__)
152 pData[chainsProcessed].nIndexE |= (chainrow & (0xFFFFFFFFFFFFFFFFI64 >> m_pHeader->rti_cplength)) >> m_pHeader->rti_startptlength;
154 pData[chainsProcessed].nIndexE |= (chainrow & (0xFFFFFFFFFFFFFFFFllu >> m_pHeader->rti_cplength)) >> m_pHeader->rti_startptlength;
156 //pData[chainsProcessed].nCheckPoint = (chainrow >> m_pHeader->rti_startptlength + m_pHeader->rti_endptlength);
160 numChains = chainsProcessed;
161 m_chainPosition += numChains;