{
  "id": 4550717,
  "title": "True Randomness in Laravel with Lararand",
  "url": "https://urgent.news/2026/08/31/true-randomness-in-laravel-with-lararand",
  "topic": "tech",
  "section": "Tech",
  "published": "2026-08-31T02:19:10.000Z",
  "source": {
    "name": "Dev.to",
    "slug": "dev-to",
    "url": "https://dev.to/edulazaro/randomness-in-laravel-with-lararand-46n6"
  },
  "original_language": "en",
  "account": "Dealing cards from a tarot deck using PHP can lead to biased results due to the way random_bytes() produces numbers. The issue arises because a byte holds 256 values, while a deck has 78 cards. The largest multiple of 78 that fits into 256 is 234 (78 × 3), leaving 22 values that wrap around and appear four times instead of three. This causes 22 cards to show up 33% more often than the other 56 cards.\n\nTests that check for the correct range pass, even though the distribution reveals the bias. To fix this, rejection sampling can be used: discard the bytes that land in the uneven tail and draw again. This ensures each card has an equal chance of appearing. This fix should be implemented once in a codebase rather than in every function that turns bytes into numbers.\n\nThe same modulo bias problem applies to shuffling arrays. The incorrect method of swapping each position with any other position leads to some permutations being more frequent than others. The correct approach is to swap each position with another position at or below the current one, which avoids the modulo bias.\n\nFor applications where the randomness is essential, such as lottery draws or regulated processes, a reliable solution is crucial. Instead of relying on the built-in random_int, a package like lararand can be used. This package allows the use of multiple randomness sources, such as quantum vacuum noise, atmospheric noise, or the system CSPRNG. The sources are tried left to right, and the first one that provides valid bytes is used. This approach ensures the randomness is not compromised and visible in the configuration file for easy review and adjustment.",
  "summary": "Here is a line of PHP that deals a card from a tarot deck. It is wrong. $card = ord ( random_bytes ( 1 )) % 78 ; Not wrong in the way a linter finds. It returns a number between 0 and 77 every single time. It never throws. Every test you would think to write about it passes: the range is right, the values are distinct, the distribution looks fine if you eyeball a hundred draws. It is wrong in the…",
  "key_points": [
    "Modulo bias in randombytes() leads to uneven card distribution",
    "Rejection sampling fixes bias by discarding uneven tail bytes",
    "lararand package provides reliable randomness for regulated processes"
  ],
  "editors_take": "Using a package like lararand can ensure reliable randomness in applications such as lottery draws or regulated processes by utilizing multiple randomness sources and avoiding modulo bias.",
  "illustration": null,
  "coverage": {
    "outlets": 1,
    "also_reported_by": []
  },
  "ai_generated": true,
  "disclaimer": "Summaries, key points and the editor’s take are written by software from other outlets’ reporting and may contain errors — always check the linked original."
}