Hash for verifying both compressed and uncompressed data?
In most situations you probably don't want to have D and compress(D) to have the same hash value, as that leads to hash collisions.  Usually hash functions are designed to avoid hash collisions -- and this is a good thing.  For instance, in cryptographic contexts, any hash scheme that has the properties you ask for would automatically be considered cryptographically insecure.

Therefore, trying to design a hash function with this property is probably a bad idea.  Instead, you should probably use the alternative solution: when you verify a hash value, hash both the data D and the compressed version compress(D) and see if either of those hash digests match the expected value.  That's probably a much better solution in practice.



If you absolutely must achieve this by artificially introducing collisions into your hash, here is a way you can do it.  Disclaimer: This is totally theoretical; it is not useful in practice.

Define the verify procedure as follows:

Verify(D, Y):
1. If Hash(D)==Y or Hash(Compress(D))==Y or Hash(Uncompress(D))==Y, return true; otherwise, return false.


Yes, this is totally trivial.

No, I don't think you'll find anything that is faster than this and that also satisfies the properties to be a good hash function.  Hash functions are specifically designed to avoid having any mathematical structure, while at the same time being very fast.  Mathematical structure is considered a weakness in a hash function.  In contrast, you are asking for a hash function with some structure.  Inserting such artificial structure into the hash function might be possible, but the natural ways of doing it probably will either introduce lots of bias into the hash function (e.g., lots of collisions) or slow it down a lot.

To put it another way, right now hash functions are optimized to meet two criteria:


Be fast.
Be "random-looking" (few collisions, unbiased, etc).


You are proposing to look for a hash function that meets three criteria:


Be fast.
Be "random-looking" (few collisions, unbiased, etc).
Also, satisfy the additional properties you requested that verify(compress(D), getHash(D)) == verify(D, getHash(compress(D))) == verify(D, getHash(D)) == true.


Obviously, it's harder to meet three criteria than to meet two.  If you want to meet three criteria, something will have to give: and in your situation, that means the resulting hash function will either be slower or less "random-looking" than standard hash functions (probably significantly so).  

So, I don't expect there's any better solution for what you want.  Instead, just do the natural solution you mention of hashing twice.