@luke_wilson180 Use Str::random(4) and then check it’s unique (and generate a new one if it isn’t); or use something like hashids.
Generate random unique 4 character code
Hi, I have users who can enter a unique code to join a class. How do I generate a random code that is completely unique when a class is created and add it to the database. I can use the max function and then +1 however it means students will be able to predict class codes. Any Ideas?
@martinbean Thanks, I actually was using this but I could get the unique part to work. Would that be done via a If Statement or is there a way to use Rule::unique along with Str::random()?
Make a function that generates a 4 character code. Check it is unique. If it is, you return it. If it isn't you return the function calling itself
function uniq() {
$u = Str::random(4);
if (check if unique) {
return $u;
}
return uniq();
}
But personally I would go with hashids as suggested by Martin
The hashid would be the hash of the class primary key (1,2,3,4 etc) so will always be unique, but unguessable.
You decode the hash after they keyed it and check if the class with that integer key exists
Thanks everyone, seems clear that hashID is the preferred option. How would I create a hashID of an ID when the ID is not yet know yet because it Auto increments? So I have a ID and a Code column but they both get created at the same time so how could I create a HashID of an ID that is not yet created in the database?
@luke_wilson180 let the column be nullable and create it without a value. Then add it after the fact. Or just add an accessor to create it on the fly (not in database)
@luke_wilson180 You don’t need to generate/save the hashid. It’s a value based on the primary key. It’s psuedo-random but unique, and reversible. So you can get a hashid from an ID, but you can also reverse a hashid back to its original value to look up models if you need to.
@luke_wilson180 You don't need to store the hashid you create it on the fly possibly using a model accessor
To ensure your HashIDs are unguessable, you can define a salt when initiating the HashIDs class. You could use your app.key for this, although I'd suggest generating a storing a new key as an extra layer of security.
$hashids = new Hashids\Hashids('this is my salt');
I can provide more code if you're not sure what I mean. :-)
Hey Everyone, thanks for your suggestions. SO I have tried using it but I am still very confused. When I try to hash the Subject ID I get no value returned when I do ddd. Am I understanding this right or where am I going wrong?
$hashids = new Hashids();
$id = DB::table('subjects')->get('id');
$hashid = $hashids->encode($id);
$subjects = Subject::all();
return view('teacher.subjects.index',
['subjects' => $subjects, $hashid]
);
@luke_wilson180 give it a seed and make sure you have the id. You can use dd() at each step
$hashids = new Hashids('foobar');
$row = DB::table('subjects')->first();
$hashid = $hashids->encode($row->id);
Okay after much hassle I think I got it working. I added another column 'code' for simplicity. I done a on button click generate a code using the current id and that seemed to do the trick.
Thanks everyone for the help. Much appreciated!!!!
public function update(Subject $subject)
{
$hashids = new Hashids('foobar', 4);
$hashid = $hashids->encode($subject->id);
$attributes = ([
'code' => $hashid]);
$subject->update($attributes);
return back()->with('success', 'Code Updated!');
}
@luke_wilson180 as we said earlier, you don't actually need to save it if you don't want to
On the Subject class
public function getHashAttribute()
{
$hashids = new Hashids('foobar', 4);
return $hashids->encode($this->id);
}
This will always return the same hash
And if you get a hash id, you can convert it to an id very easy as well
$hashids = new Hashids('foobar', 4);
$subject = Subject::find($hashids->decode($hash));
Please or to participate in this conversation.