The following post is from Nov. 14. Programmers what do you think? I think we need to figure out how/what happened here it may be the only smoking gun in OH regagarding tabulation fraud:
On edit the original thread from Nov. 14:
http://www.democraticunderground.com/discuss/duboard.php?az=view_all&address=203x48519Originally posted by DU memeber WhiteKnight
/*
About me:
I have a graduate degree in computer science, and more than 15 years of experience as a software engineer working with highly reliable systems.I have a knack for looking at the results of software failures and figuring out what's wrong with the code. For now, I prefer to remain anonymous and will go by the handle: WhiteKnight
(email: whiteknightfordemocracy@yahoo.com ).
About the bizzare vote counts in one Ohio Precinct:
After seeing the Associated Press story titled "Machine Error Gives Bush Extra Ohio Votes", I started thinking about the numbers reported in the story, whichare:
Votes for Bush: 4258
Votes for Kerry: 260
Total number of voters: 638
It also says that Bush "actually received 365 votes". That means there must have been 13 votes for other candidates (638-260-365 = 13).
I wondered how this result could have been produced. They called it a "failure", but I know a lot about how systems can fail, and this sounded fishy. Why were Kerry's vote totals recorded properly, but not Bush's? It's much more likely that a system failure would cause either no vote totals to be recorded at all, or that both totals would be corrupted.
I suppose it could have been a hardware failure that occurred right after Kerry's vote total had been written to storage, and just as Bush's was being written. But that's likely to be a very narrow time window. It's possible, but sounds like a very rare failure mode. It just seems odd that out of the whole universe of possible failures, we get a failure that records Kerry's votes correctly, and corrupts Bush's total.
Think of it this way: In basketball you know there are many ways a shot can fail to go in. It can go off the glass and miss, it can bounce off the front of the rim, rattle out, airball etc... etc... But there is one particular failed shot that's very rare: when the ball comes in at just the right trajectory with just the right speed, and it lodges between the rim and the backboard - just sticks there. I've seen it happen maybe a couple of times in years of watching the NBA.
So think of the odds of a failure that records Kerry's votes correctly, but corrupts Bush's as analogous to the ball jamming there between the rim and backboard. Pretty rare failure huh? Well, it gets even worse:
Why was the number off by only several thousand?
If the votes are added up using a 4 byte unsigned integer, then the possible values range from 0 to 4,294,967,296 (over 4 Billion). If a random bit error or hardware storage error occurred, then why didn't Bush get say 3,239,568 extra votes in this particular "failure"? Most true failures would result in some wild number that you would immediately recognize as garbage.
The analogy here is: not only did the basketball lodge between rim and glass, but the Spalding logo ended up perfectly horizontal, aligned front and center.
Given all of this, I decided to explore ways that vote counting software could end up with these particular results. Was someone adding a percentage to the Bush votes? Was there some multiplier involved?
After thinking about it for an hour or so, I decided to take a different tack: think like the person who is trying to rig the election. What would you do? You wouldn't really want to change the total number of voters. That might be too easy to detect given people being checked off on voter roles. Instead you would want to shift votes from one candidate to another. Maybe every 10th vote for kerry, you'd instead give to Bush.
OK, that's pretty easy to program, but it wouldn't expain the bizzare results in this one precinct in Ohio. But... what if the evil programmer made a mistake? Maybe one line of code had an error they didn't catch.
I decided to write a small vote counting program, and add in a function to steal every 10th vote. Once that was working I'd introduce a small error and see if the results came close the Ohio results reported by AP.
The program below is the result.
As you will see, there is one line of code that is supposed to add a stolen vote to Bush's total, and should be written as:
b = b + 1;
but (I theorize) it was mis-typed as:
b = b + k;
So instead of adding one stolen vote to Bush's total, it adds the running total of Kerry votes to Bush's total. Whoops!
The output from the program with the typo in place is:
starting election
Election results: b: 4258 k: 260 o: 13
(the actual votes: b: 336 k: 288 o: 14)
The output from the program with the typo corrected is:
starting election
Election results: b: 365 k: 260 o: 13
(the actual votes: b: 336 k: 288 o: 14)
So the intent was to shift 29 votes from other candidates to Bush, but the one-line programming mistake gives him an extra 3922 votes.
I'm not saying this proves that this is what happened, but it does indeed prove that a small, one-line programming error by an evildoer programmer could produce the results seen in this one Ohio precinct.
-WhiteKnight
p.s. Please circulate this as far and wide as possible. Thanks!
*/
#include <stdio.h>
#include <string.h>
// Vote totals for b=Bush k=Kery o=Other
int b=0, k=0, o=0;
// The set of "real" books:
int breal=0, kreal=0, oreal=0;
//
// Here's the hypothetical "patch" that the evildoer programmer
// might have written:
//
void robOhio(int creal, int* c) {
// Look for every 10th vote from this candidate:
if ((creal % 10)==0) {
// OK, here's the bug. Should have been
// b = b + 1;
// Give the vote to b
b = b + k;
// Take it away from other candidate:
*c = *c - 1;
}
}
int main() {
char votes<1000>;
//
// Here are the votes in a hypothetical order that I made up.
// So in this example, the first two votes went to Kerry, the
// next two to Bush, then one for Kery, one for Bush, one for
// Other, and so on.
//
// The order of the votes does affect the final numbers but,
// even if you change the order, the rough order of magnetude
// of the bogus results stays about the same.
//
//0 1 2 3 4 5
//12345678901234567890123456789012345678901234567890
strcpy(votes,"KKBBKBOKBBKKBBKBBKBBKKBBKBBKBBKKBBKBBKBBKKBBKBBKBB"); // 50
strcat(votes,"KKBBKBKKOBKKBBKBBKBBKKBBKBBKOBKKBKKBKKBBKKBBKBBKBB"); // 100
strcat(votes,"KKBBKBBKBKKKBBKBBKBBKKBOKBBKBBKKBKKBBKBBKKBBKBBKBB"); // 150
strcat(votes,"KKBKKBBKKBKKBKKBBKBBKKBBKBBKBOKKBKKKBKBBKKBBKBBKBB"); // 200
strcat(votes,"KKBKBBBKBBKKBKKBBKBBKKKBKBBKBOKKKBKBBKBBKKBBKBBKBB"); // 250
strcat(votes,"KKBBKBBKBBKKBKKBBKBBKKBBKBOKBBKKBKKBBKBBKKBBKBBKBB"); // 300
strcat(votes,"KKKBKBBKBBKKKBKBKKBBKKBKKOKKBKKKBBKBBKBBKKBBKBBKBB"); // 350
strcat(votes,"KKBKKBBKBBKKBBKKBKBOKKBKKBBKBBKKBBKBBKBBKKBBKBBKBB"); // 400
strcat(votes,"KKBKKBBKBBKKBBKBBKBBKBBKKBBKBBKKBBKBBKBBKKBBKBBKBB"); // 450
strcat(votes,"BKKBKBBKBBKKBBKBBKBBKKBKKBBKBBKKBKKBBKBBKKBBKBBKBB"); // 500
strcat(votes,"KKKBKBBKBBKKBBKBBKBBKKBBKBBKBBKKBKKBBKBBKKBBKBBKBB"); // 550
strcat(votes,"KKBBKBBKBBKKBBKBBKBBKKKKKBBKBKKKBOKBBKBBKKBBKBBKBB"); // 600
strcat(votes,"KKBBKBBKBBKKBBKBBKOBKOBKKBOKBOKKBBKBBK"); // 638
printf("starting election\n");
// Start counting votes:
for (int i=0; i<strlen(votes); i++) {
char v = votes;
if (v=='B') {
b = b + 1;
breal = breal + 1;
} else if (v=='K') {
k = k + 1;
kreal = kreal + 1;
// This is not a vote for b, so steal some votes:
robOhio(kreal, &k);
} else if (v=='O') {
o = o + 1;
oreal = oreal + 1;
// This is not a vote for b, so steal some votes:
robOhio(oreal, &o);
}
}
printf("Election results: b: %d k: %d o: %d\n",b,k,o);
printf("(the actual votes: b: %d k: %d o: %d)\n",breal,kreal,oreal);
}