Just nitpicking, but you probably don't want random key generation, key generation should be deterministic, but it should generate an even distribution in the key space.
If you consider only random collisions, then the first approach is almost perfect. You must prefix the strings with their length so that you do not get collisions when the substring moves from one parameter to another. Given md5, the avalanche features are pretty good, which ensures that random collisions are rare enough to be ignored.
But be careful with MD5, if you handle user input, it knows collision attacks. If an untrusted user can choose arbitrary bytes for function parameters, and returning an incorrect result can have security implications, then you have a security hole. For example, if you use this information to cache authorization, an attacker could work out two sets of parameters, the hash of which has the same value. One could gain access to something public, and to another - to a protected service. Now just request authorization with the first set, get authorization, and then get access to the secure service with another set, receiving a green light from cached authorization.
source share