"qui expire après une utilisation", sans bdd (ou au pire un fichier) pour stocker les id déja utilisées je vois pas bien
Pour ce qui est d'une id protégé a passer en get, c'est pas bien compliquer : tu peux générer un id aléatoire de 6 caractères, par exemple, le passer dans un salt + hash, et garder les 6 premiers caractères de ce hash que tu concatène aux 6 de l'ID. Ca te fait un pass de 12 caractères au total a passer en get.
Pour valider l'ID, tu recup les 6 premiers caracteres du get, ajoute le salt, hash, et compare les 6 premiers caractères du hash aux 6 dernier du pass.
Note qu'en utilisant ce type de script, tu peux creer un lien valide pour un temps donné, si tu utilises le timestamp comme ID (lorsque tu recoit une requete avec ce lien, il faut récup' le timestamp du lien (10 chiffres, je crois), verifier que le timestamp actuel est dans la marge que tu permets (dans l'heure suivant le generation du premier timestamp, par exemple), et enfin confirmer qu'il sagit d'un vrai en passant le timestamp recu dans ton salt + hash).