Every log file in the SourceSafe \vss\data\a-z directories is associated with a number. These algorithms convert one to the other...
PhyToNum
Microsoft publish the algorithm for physical to number conversion in Article ID Q171350.
To verify this requires an arbitrary precision calculator. A nice one is provided by The GNU Multiple Precision Arithmetic Library. Click on the 'Try GMP' link to locate the calculator.
This example shows how it works: a=0, b=1 ... z=25
zzzzzzzz Decimal Hex
||||||||___ 25 + ( 0 ) = 25 19
|||||||____ 25 + ( 26 * 25 ) = 675 2a3
||||||_____ 25 + ( 26*26 * 675 ) = 17575 44a7
|||||______ 25 + ( 26*26*26 * 17575 ) = 456975 6f90f
||||_______ 25 + ( 26*26*26*26 * 456975 ) = 11881375 b54b9f
|||________ 25 + ( 26*26*26*26*26 * 11881375 ) = 308915775 1269ae3f
||_________ 25 + ( 26*26*26*26*26*26 * 308915775) = 8031810175 1debbb27f
|__________ 25 + ( 26*26*26*26*26*26*26 * 8031810175) = 208827064575 309f1020ff
abcdwxyz Decimal Hex
||||||||___ 25 + ( 0 ) = 25 19
|||||||____ 24 + ( 26 * 25 ) = 674 2a2
||||||_____ 23 + ( 26*26 * 674 ) = 17547 448b
|||||______ 22 + ( 26*26*26 * 17547 ) = 456244 6f634
||||_______ 3 + ( 26*26*26*26 * 456244 ) = 11862347 b5014b
|||________ 2 + ( 26*26*26*26*26 * 11862347 ) = 3 08421024 126221a0
||_________ 1 + ( 26*26*26*26*26*26 * 308421024 ) = 8018946625 1ddf76a41
|__________ 0 + ( 26*26*26*26*26*26*26 * 8018946625 ) = 208492612250 308b20ca9a
__int64 PhyToNum(char *szFile) {
__int64 i64FileNum = 0; // Counter for file Number
int i; // Loop Variable
for( i=7; i >= 0; i-- ) { // Start from right of filename
i64FileNum *= 26; // Next power of 26
i64FileNum += (__int64)(toupper(szFile[i]) - 'A'); // Convert the value
}
return (i64FileNum);
}
NumToPhy
The inverse function Microsoft do not publish.
The function converts the file number to a lower case 8 character physical name
This example shows how it works. Note that:
32bit = 2 power 32 = 4,294,967,296 = 4GB 64bit = 2 power 64 = 18,446,744,073,709,551,616 = 18.44 Million Terrabytes = 0x100000000
Number 208827064575 divided by 26*26*26*26*26*26*26 = 25 ---------------- 8031810176
remainder 8031810175 divided by 26*26*26*26*26*26 = 25 -------------- | 308915776
remainder 308915775 divided by 26*26*26*26*26 = 25 ------------ | | 11881376
remainder 11881375 divided by 26*26*26*26 = 25 ---------- | | | 456976
remainder 456975 divided by 26*26*26 = 25 -------- | | | | 17576
remainder 17575 divided by 26*26 = 25 ------ | | | | | 676
remainder 675 divided by 26 = 25 ---- | | | | | | 26
remainder 25 -- | | | | | | | 0
| | | | | | | |
z z z z z z z z
Number 208492612250 divided by 26*26*26*26*26*26*26 = 25 ---------------- 8031810176
remainder 7697357850 divided by 26*26*26*26*26*26 = 24 -------------- | 308915776
remainder 283379226 divided by 26*26*26*26*26 = 23 ------------ | | 11881376
remainder 10107578 divided by 26*26*26*26 = 22 ---------- | | | 456976
remainder 54106 divided by 26*26*26 = 3 -------- | | | | 17576
remainder 1378 divided by 26*26 = 2 ------ | | | | | 676
remainder 26 divided by 26 = 1 ---- | | | | | | 26
remainder 0 -- | | | | | | | 0
| | | | | | | |
a b c d w x y z
void NumToPhy(char *szFile, __int64 i64FileNum) {
int i; // Loop variable
int c; // Character value a=0 z=25
__int64 i64Power;
int p;
strcpy(szFile, " ");
// Start from the right of the filename
for( i=7; i >= 0; i-- ) {
for ( p = 0, i64Power=1; p < i; p++) {
i64Power = i64Power*26;
}
c = (int) (i64FileNum / i64Power); // 0-25
szFile[i] = (char) (c + 'a'); // cast to lower case character
i64FileNum = i64FileNum % i64Power; // Calc remainder for next digit
}
}
HexStrTo__Int64
This function isn't used by either of the conversion functions but it's useful for capturing input.
__int64 HexStrTo__int64(char *cp) {
unsigned int i = 0;
__int64 j = 0;
while (cp && *cp && isxdigit(*cp)) {
i = *cp++ - '0';
if (9 < i)
i -= 7;
j <<= 4;
j |= (i & 0x0f);
}
return(j);
}
|