Yes, it is a common part of all save/load systems.is there a way to bind a name to a code to replace a hero with another hero and only that player may use that code to replace that hero?
Yes, it is a common part of all save/load systems.
The simplest implementation is to save a "hash" of the player name as an element inside the code. Since code length is important you can merge the player name hash with the code checksum. This is usually done with xor operation however due to WC3 lacking that you can get away with addition (which is similar in many ways).
The result is that if a player with a different account name uses the code the checksum does not match up with the payload so the load attempt can be rejected as "corrupted".
Alternatively you can use the account name as part of an encryption process for similar results. If the wrong account uses the code it will decrypt to garbage and so the checksum will fail to match so the code can be rejected as corrupted.
You push the user name through the string hash function (I think it has something to do with "key" in GUI, but basically it is a native string hasher). The output is a full range 32bit which is deterministic based on input and is case-insensitive (so does support player name case changes at the battlenet login screen). This is often too large for codes that do not need strong protection so you can shorten it by either dividing or modulating by an appropriate amount. Best protection needs all 32 bits of information however, anything less runs high chances of collisions.
For extra security add secret keys and other reversible transformations to both the code checksum and the player name hash. These make it less apparent that standard algorithms are in use and so harder to crack without resorting to reverse engineering.
set udg_intvar = StringHash(GetPlayerName(Player(0)))