Hashing would work, but there is another element you are missing. In order to generate a hash value that cannot be regenerated, then you need to include a secret value in the hash. A GUID would work, but it can really be any value that your customer doesn't know. Of course if they have the software on their computer, then they could conceivably discover the algorithm and the secret value, thus circumventing it. Using a different secret value for each customer would be a nice extra level of protection just in case one customer discovers it.
Example:
Hash([Table Data] + [Secret Value]) = [stored hash]
If you only do a hash of the table data, then they can simply rehash the modified table data, and then you won't know they have done it.
As far as how to hash the entire table, instead of each row, most hashes support incremental hashing. The reason is if you are hashing a 10 GB file, you probably don't have enough RAM to load it all into memory to work on. Instead you hash one block at a time, and then when you are done you finalize the hash. You can use this same method on your data. Simply add each row to the hash, one at a time, and when you are done finalize the hash. Of course remember to include your secret key value.
Some things to keep in mind:
- Don't include the validation routine in your application - in other words don't provide a way for them to validate that their attempted hack worked or failed. Doing so will give them immediate feedback and allow them to engineer an eventual solution.
- Make sure you test this system well, especially if you plan to penalize your customer if these hashes fail.
- Make sure you customer is aware that tampering with these values is forbidden. It might be a good idea to combine it with table level encryption to prevent accidental modifications.
- You might be better off logging the charges off site. If the server is connected to the internet, then have it send the information to a web service you run. For even better security have the web service validate the messages and respond with a key. Then you can validate that key locally to make sure they haven't circumvented the web service. This would be a great application of public key message signing.
Also keep in mind that most people are honest, and many people will only resort to circumvention if the path of honesty is too painful (i.e. false positives on the tests, or too expensive of a price tag.) Often times those who would steal it wouldn't pay for it anyway. Others who might steal today may pay tomorrow. You don't want to battle your customers and treat them as your enemy because then you both loose.