For this example, the first 18 digits of our key are 111122222223333333.
The user entered key is first split into 2 parts, the first 18 characters and the remaining 4 characters. It then calculates the checksum for the first 18 digits in the function starting at address 004061c0.
The program then pads the first 18 characters with 5 zeros at the beginning and end - 0000011112222222333333300000. This is all the first 170 lines of this function seems to do. It then takes the augmented key 7 characters at a time and runs it through the actual checksum, which as Nathan stated in the video just converts it from a decimal to hexidecimal (so 0000011 -> 0xB, 1122222 -> 0x111FAE etc...) - it keeps a running total but reduces it mod 0x43 after each addition. Call this final reduced total 'a'.
if (0 < (int)(~uVar4 - 1)) {
do {
_strncpy((char *)local_40,(char *)((int)&local_20 + iVar10),7);
local_39 = 0;
iVar2 = checksum_calc_2(this,local_40);
iVar10 = iVar10 + 7;
iVar5 = (iVar2 + iVar5) % lit_hex_43;
} while (iVar10 < (int)(~uVar4 - 1));
It then pads the end of the first 18 characters with 2 zeros (11112222222333333300) and does exactly the same process but in blocks of 5 characters instead, and reducing mod 0x59 after each addition. Call this final reduced total 'b'.
if (0 < (int)(~uVar4 - 1)) {
do {
_strncpy((char *)local_40,local_38 + iVar2,5);
local_3b = 0;
iVar3 = checksum_calc_2(this_00,local_40);
iVar2 = iVar2 + 5;
iVar10 = (iVar3 + iVar10) % lit_hex_59;
} while (iVar2 < (int)(~uVar4 - 1));
}
It then calculates the 'final' checksum for the first 18 characters as (a * 100) + b
return iVar5 * 100 + iVar10;
The result of doing that in our example is 0x1565 (decimal 5477). So our complete code is 1111222222233333335477.
I've written some terrible c++ that will generate a valid key - all it does is create a string with 18 random digits in and calculates what the final 4 digits should be for the key to be valid.
I suspect the use of the magic numbers 0x43 and 0x59 are so that EA could use the same keygen algorithm with different games by changing them to give a superficially different algorithm. As an example, F1 2002 uses an identical keycheck program, with the only change being that it uses the magic numbers 0x17 and 0x59 instead. They are loaded into some object in a marginally obfuscated way at address 00401841 in both F1 2002 and Nightfire.
This is the same algorithm used in Nathan's Black and White video as well - it just uses magic numbers 0x53 and 0x61 instead.