]> git.sesse.net Git - freerainbowtables/blob - Common/rt api/RTI2Reader.cpp
cd1e85d163f32f313092f2b628a43fb4dbaeda27
[freerainbowtables] / Common / rt api / RTI2Reader.cpp
1 /*
2  * freerainbowtables is a project for generating, distributing, and using
3  * perfect rainbow tables
4  *
5  * Copyright 2010, 2011 Martin Westergaard Jørgensen <martinwj2005@gmail.com>
6  * Copyright 2010, 2011 James Nobis <frt@quelrod.net>
7  *
8  * This file is part of freerainbowtables.
9  *
10  * freerainbowtables is free software: you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation, either version 2 of the License, or
13  * (at your option) any later version.
14  *
15  * freerainbowtables is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with freerainbowtables.  If not, see <http://www.gnu.org/licenses/>.
22  */
23
24 #include "RTI2Reader.h"
25
26 #include <math.h>
27
28 RTI2Header *RTI2Reader::m_pHeader = NULL;
29 RTI2Reader::RTI2Reader(string Filename)
30 {
31         //m_pIndexPos = NULL, m_pChainPos = NULL;;
32         m_pIndex = NULL;
33         m_pFile = fopen(Filename.c_str(), "rb");
34         if(m_pFile == NULL)
35         {
36                 printf("Unable to open file %s", Filename.c_str());
37                 exit(1);
38         }
39         FILE *pFileIndex = fopen(Filename.append(".index").c_str(), "rb");
40         if(pFileIndex == NULL)
41         {
42                 printf("Unable to open file %s", Filename.append(".index").c_str());
43                 exit(1);
44         }
45         m_chainPosition = 0;
46
47         long len = GetFileLen(pFileIndex);
48         fseek(pFileIndex, 0, SEEK_SET);
49
50         m_pIndex = new (nothrow) unsigned char[len];
51         if(m_pIndex == NULL) {
52                 printf("Error allocating %ld MB memory for index in RTI2Reader::RTI2Reader()", len / (1024 * 1024));
53                 exit(-2);
54         }
55         if(fread(m_pIndex, 1, len, pFileIndex) != (unsigned long)len)
56         {
57                 printf("Error while reading index file");
58                 exit(1);
59         }
60         fclose(pFileIndex);
61         m_pHeader = new RTI2Header();   
62         memcpy(m_pHeader, m_pIndex, sizeof(RTI2Header));
63         m_pHeader->m_cppos = (unsigned int*)(m_pIndex + 8);
64         m_pHeader->prefixstart = *(uint64*)(m_pIndex + 8 + (m_pHeader->rti_cplength * 4));
65         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
66         m_indexrowsizebytes = (uint32)ceil((float)m_pHeader->rti_index_numchainslength / 8);
67         // Check the filesize
68         fseek(m_pFile, 0, SEEK_END);
69         len = ftell(m_pFile);
70         fseek(m_pFile, 0, SEEK_SET);
71         if(len % m_chainsizebytes > 0)
72         {
73                 printf("Invalid filesize %lu\n", len);
74                 return;
75         }
76         
77
78 }
79
80 RTI2Reader::~RTI2Reader(void)
81 {
82         if(m_pIndex != NULL) delete m_pIndex;
83         if(m_pFile != NULL) fclose(m_pFile);
84
85 }
86
87 unsigned int RTI2Reader::GetChainsLeft()
88 {
89         long len = GetFileLen(m_pFile);
90         return len / m_chainsizebytes - m_chainPosition;
91 }
92
93 int RTI2Reader::ReadChains(unsigned int &numChains, RainbowChain *pData)
94 {
95         if(strncmp(m_pHeader->header, "RTI2", 4) != 0)
96         {
97                 numChains = 0;
98                 return -1;
99         }
100         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
101         unsigned int i = 0;
102         unsigned int indexRow = 0; // Current offset into the index
103         unsigned int curRowPosition = 0;
104         
105         while(true) // Fast forward to current position
106         {
107                 // ALERT: Possible problem here if m_indexrowsizebytes > 1 as pNumChains is a unsigned char.
108                 unsigned int NumChainsInRow = (unsigned int)*(pNumChains + indexRow * m_indexrowsizebytes);
109                 if(m_indexrowsizebytes > 1)
110                 {
111                         //XXX Have to find a solution to this problem
112                         printf( "FATAL: m_indexrowsizebytes > 1: %d\n", m_indexrowsizebytes ); 
113                         exit(2);
114                 }
115                 if(i + NumChainsInRow > m_chainPosition)
116                 {
117                         curRowPosition = m_chainPosition - i;
118                         break; // The current position is somewhere within this prefix
119                 }
120                 indexRow++;             
121                 i += NumChainsInRow;
122         }
123         
124         uint64 chainrow = 0; // Buffer to store a single read chain
125         unsigned int chainsProcessed = 0; // Number of chains processed
126
127         // XXX: same problem with unsigned char here.
128         unsigned int NumChainsInRow = *(pNumChains + indexRow);
129         while(chainsProcessed < numChains && fread(&chainrow, 1, m_chainsizebytes, m_pFile) == m_chainsizebytes)
130         {
131                 if(curRowPosition >= NumChainsInRow)
132                 { // Skip to next index row position
133                         indexRow++;
134                         curRowPosition = 0;
135                         NumChainsInRow = *(pNumChains + indexRow);
136                 }
137                 while(NumChainsInRow == 0) // We skip forward until we hit a index with > 0 chains
138                 {
139                         indexRow++;
140                         NumChainsInRow = *(pNumChains + indexRow);
141                         curRowPosition = 0;
142                 }
143                 // Load the starting point from the data
144                 pData[chainsProcessed].nIndexS = chainrow << ( 64 - m_pHeader->rti_startptlength );
145                 pData[chainsProcessed].nIndexS = pData[chainsProcessed].nIndexS >> ( 64 - m_pHeader->rti_startptlength );
146
147                 // Load the ending point prefix 
148                 pData[chainsProcessed].nIndexE = ( m_pHeader->prefixstart + indexRow ) << m_pHeader->rti_endptlength;
149                 // Append the ending point suffix
150 #if defined(_WIN32) && !defined(__GNUC__)
151                 pData[chainsProcessed].nIndexE |= (chainrow & (0xFFFFFFFFFFFFFFFFI64 >> m_pHeader->rti_cplength)) >> m_pHeader->rti_startptlength;
152 #else
153                 pData[chainsProcessed].nIndexE |= (chainrow & (0xFFFFFFFFFFFFFFFFllu >> m_pHeader->rti_cplength)) >> m_pHeader->rti_startptlength;
154 #endif
155                 //pData[chainsProcessed].nCheckPoint = (chainrow >> m_pHeader->rti_startptlength + m_pHeader->rti_endptlength);
156                 curRowPosition++;
157                 chainsProcessed++;
158         }
159         numChains = chainsProcessed;
160         m_chainPosition += numChains;
161         return 0;
162 }