I agree with @schroeder that password reset emails are one of the areas where it tends to be more acceptable to instruct users to click on links. After all, the user was the one that triggered the password reset and should be expecting an email. You could add text in the email that says "This email was sent due to your request. If you did not request a password reset then do not click this link. Normally you should not click any links in an unexpected email, even if it appears to be legitimate."
The reason I encourage you to reconsider this is because your alternative (using a PIN) is going to be more complicated for users and will likely cause more headaches for you. The PIN complexity aside for a moment, you are going to have to instruct users on what to do, and these instructions will necessitate you telling them where on your site to go to enter the code. While saying "Go to our site home page, click Forgotten Password, and click Enter Reset PIN" isn't rocket science you will still have users complain that they can't find the buttons or otherwise get confused about what to do. Having them simply click on a link eliminates a lot of this confusion.
With regards to PIN complexity you should be able to do a few things to counteract the reduced 'keyspace' of a random 6 digit PIN compared to your hash. You can add in letters and some symbols to bump up the number of possible combinations. You could prompt the user not only for their reset PIN but also their email address (which requires an attacker to guess more than just a valid PIN). You could also add a CAPTCHA or other 'liveness' check to hinder automated guessing at PIN input. Finally, you can monitor PIN reset attempts and block IPs (or otherwise delay them) that submit a large number of guesses.
Just like with a link-based password reset function these PINs should only be valid for a single use and should expire within 30-60 minutes, regardless of whether they are used or not.
By taking steps like these you can eliminate the more likely threats against a PIN-based password reset system.
/dev/urandom
and then encode them with a human-friendly format like Base64. And why can't you include this token as plaintext?