pragma solidity 0.4.24; contract RNG { /** * @dev Given a number returns a slice of any bits, at certain offset * @author flockonus (https://gist.github.com/flockonus/cb75838d78cf544744e7ac95ab3ec431) * @param number A number to be sliced * @param nbits How many bits long is the new number * @param offset How many bits to skip * @return A slice of the number, as an uint */ function sliceNumber(uint256 number, uint256 nbits, uint256 offset) public pure returns (uint256) { /* Mask is made by shifting left an offset number of times */ uint256 mask = uint256((2 ** nbits) - 1) << offset; /* AND number with mask, and trim to max of nbits bits */ return uint256((number & mask) >> offset); } /** * @dev Returns an array with random numbers * Implementation of a technique described here https://github.com/axiomzen/eth-random * @param count How many random numbers will be returned * @param power How big the numbers will be (in bits) * @return An array with random numbers */ function getRandomNumbers(uint256 count, uint256 power) public view returns (uint256[]) { /* We start from the block number and its hash */ uint256 ddb = uint256(blockhash(block.number - 1)); uint256 r = uint256(keccak256(abi.encodePacked(ddb - 1))); /* If r equals 0, we try with an higher block number */ while (r == 0) { ddb += 256; r = uint256(keccak256(abi.encodePacked(ddb - 1))); } /* We create an array to store our random numbers */ uint256[] memory numbers = new uint256[](count); for (uint256 i = 0; i < count; i += 1) { numbers[i] = sliceNumber(r, power, i); } return numbers; } }
0.4.24