Hmmm, fingerprints are well possible in a software...
If you have a strong secondary PC and lots of space on your web server, you could create user-specific versions of all downloads. In a very simplified version, you hide a redundant "MOV EAX, user_id" in a well-defined place of the code - I mean, 1) assemble "MOV EAX, 0" into the common version, 2) patch into it the user_id for each user-specific version and 3) compress/encrypt only afterwards. If your web server is strong and you don't have that many downloads, it could be done on-the-fly by the web server instead.
Then, if you see your code being ripped off and that code contains the hidden fingerprint, you'll be able to find out which user on your site stole it (or leaked it to the thief). This assumes, of course, that A) the thief is not smart enough to find the fingerprint and/or B) the ripped off code is sophisticated enough for such a fingerprint to stay well hidden in it (it does not become obvious that that particular instruction is not needed for the functionality) and C) the thief does not have access to two (or more) user-specific versions that - after decompression and decrypting - only differ in the fingerprint.
Wanna attend a polymorphic virus coding course?
[...] Or another simple example, taken from SecuROM. Whenever using constants, use "MOV EAX, (value XOR user_id XOR random_value); XOR EAX, (user_id XOR random_value)" instead of a plain "MOV EAX, value". Because of the randomness of the actual values, the user_id won't be seen anywhere "naked" but you, the author knowing the random_value for at least one such tricky assignment, can easily find out. Yes, this can be unwinded, but, when sophisticated enough, only with lots of struggles and "visual debugging" (watch the code in a disassembler and find out in your head what it does) becomes extremely annoying, too.