SkillAgentSearch skills...

RandomKit

Random data generation in Swift

Install / Use

/learn @nvzqz/RandomKit

README

RandomKit

<div align="center"> <img src="https://img.shields.io/badge/platform-ios%20%7C%20macos%20%7C%20watchos%20%7C%20tvos%20%7C%20linux-lightgrey.svg" alt="Platform"> <img src="https://img.shields.io/badge/language-swift-orange.svg" alt="Language: Swift"> <img src="https://img.shields.io/cocoapods/dt/RandomKit.svg" alt="downloads"> <br> <a href="https://cocoapods.org/pods/RandomKit"><img src="https://img.shields.io/cocoapods/v/RandomKit.svg" alt="CocoaPods - RandomKit"></a> <a href="https://github.com/Carthage/Carthage"><img src="https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat" alt="Carthage"></a> <a href="https://gitter.im/nvzqz/RandomKit?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge"><img src="https://badges.gitter.im/Join%20Chat.svg" alt="GITTER: join chat"></a> <a href="https://codebeat.co/projects/github-com-nvzqz-randomkit"><img src="https://codebeat.co/badges/256f6b2d-fd36-4b71-8bf0-b3cb31cb95ae" alt="codebeat badge"></a> <img src="https://img.shields.io/badge/license-MIT-000000.svg" alt="License"> <a href="https://nvzqz.github.io/RandomKit/docs/"><img alt="Documented" src="https://img.shields.io/badge/documented-%E2%9C%93-brightgreen.svg"></a> <br> <a href="https://www.patreon.com/nvzqz"> <img src="https://c5.patreon.com/external/logo/become_a_patron_button.png" alt="Become a Patron!" height="35"> </a> <a href="https://www.paypal.me/nvzqz"> <img src="https://buymecoffee.intm.org/img/button-paypal-white.png" alt="Buy me a coffee" height="35"> </a> </div>

RandomKit is a Swift framework that makes random data generation simple and easy.

Build Status

| Branch | Status | | :-------: | :----: | | master | Build Status |

Installation

Compatibility

  • Platforms:
    • macOS 10.9+
    • iOS 8.0+
    • watchOS 2.0+
    • tvOS 9.0+
    • Linux
  • Xcode 8.0+
  • Swift 3.0.2+ & 4.0

RandomKit is possibly also compatible with FreeBSD, Android, and Windows (under Cygwin) but has not been tested for those platforms.

Install Using Swift Package Manager

The Swift Package Manager is a decentralized dependency manager for Swift.

  1. Add the project to your Package.swift.

    import PackageDescription
    
    let package = Package(
        name: "MyAwesomeProject",
        dependencies: [
            .Package(url: "https://github.com/nvzqz/RandomKit.git",
                     majorVersion: 5)
        ]
    )
    
  2. Import the RandomKit module.

    import RandomKit
    

Install Using CocoaPods

CocoaPods is a centralized dependency manager for Objective-C and Swift. Go here to learn more.

  1. Add the project to your Podfile.

    use_frameworks!
    
    pod 'RandomKit', '~> 5.2.3'
    

    If you want to be on the bleeding edge, replace the last line with:

    pod 'RandomKit', :git => 'https://github.com/nvzqz/RandomKit.git'
    
  2. Run pod install and open the .xcworkspace file to launch Xcode.

  3. Import the RandomKit framework.

    import RandomKit
    

Install Using Carthage

Carthage is a decentralized dependency manager for Objective-C and Swift.

  1. Add the project to your Cartfile.

    github "nvzqz/RandomKit"
    
  2. Run carthage update and follow the additional steps in order to add RandomKit to your project.

  3. Import the RandomKit framework.

    import RandomKit
    

Benchmark

Various components of RandomKit can be easily benchmarked by running benchmark.sh.

./benchmark.sh [FLAGS] [PROTOCOLS]

Use the --help flag for information regarding how to use it.

Note: The default count is 10000000, which is A LOT if using the --array flag. This can be changed by passing an argument into --count or -c.

Usage

Try it out for yourself! Download the repo and open 'RandomKit.playground'.

RandomGenerator

The RandomGenerator protocol defines basic methods for generating primitive values and randomizing a buffer.

All provided types that conform to RandomGenerator have a static default value that can be passed as an inout argument to generation functions.

let value = Int.random(using: &Xoroshiro.default)

Available Generators

  • ARC4Random

    • Because the symbols for the arc4random family of functions aren't exported with Foundation on Linux and other platforms, they're dynamically loaded at runtime.
  • DeviceRandom

    • Reads from "/dev/random" or "/dev/urandom" as its source.
  • MersenneTwister

  • Xoroshiro

  • Xorshift

  • XorshiftStar

  • ChaCha

SeedableRandomGenerator

SeedableRandomGenerator is for types that can be seeded with some associated Seed type.

RandomBytesGenerator

The RandomBytesGenerator protocol is for types that specialize in generating a specific type that fills up a number of bytes. For example, MersenneTwister specializes in generating UInt64 while Xorshift generates UInt32 values.

Thread Safety

For single-threaded programs, it is safe to use a global generator instance such as Xoroshiro.default as a source of randomness.

For multi-threaded programs, the thread-local instances should be used. This allows for different threads to use their own separate random generators without a shared mutable state.

In the following example, randomGenerator is unique to each thread.

let randomBytes = Xoroshiro.withThreadLocal { randomGenerator in
    return [UInt8](randomCount: 1000, using: &randomGenerator)
}

Thread-local generators are deallocated upon thread exit, so there's no need to worry about cleanup.

It's recommended to not call withThreadLocal(_:) or get the threadLocal pointer each individual time it's needed. Retrieving the thread-local instance incurs avoidable overhead.

// Bad
let value = Int.random(using: &Xoroshiro.threadLocal.pointee)
array.shuffle(using: &Xoroshiro.threadLocal.pointee)

// Good
let threadLocal = Xoroshiro.threadLocal
let value = Int.random(using: &threadLocal.pointee)
array.shuffle(using: &threadLocal.pointee)

// Better
Xoroshiro.withThreadLocal { randomGenerator in
    let value = Int.random(using: &randomGenerator)
    array.shuffle(using: &randomGenerator)
}

As a shortcut, you can even apply a function directly as a parameter.

let value = Xoroshiro.withThreadLocal(Int.random)

Prior to v4.4.0, thread safety could be achieved by instantiating a new seeded instance of a given RandomGenerator type. The problem with this is that unnecessary seeding occurs each time. With this, the generator is seeded once and can then be reused at later points.

Shortcuts to the reseeding version of a generator are also available:

Xoroshiro.withThreadLocalReseeding {
    ...
}

Which is way better than writing:

ReseedingRandomGenerator.withThreadLocal(createdWith: { Xoroshiro.reseeding }) {
    ...
}

Protocols

RandomKit is very protocol-oriented, which gives it the ability to be very flexible and modular.

Random

A protocol for types that can generate random values using a RandomGenerator.

RandomInRange

A protocol for types that can generate optional random values within a range using a RandomGenerator.

Int.random(in: 0 ..< 0, using: &randomGenerator) // nil

RandomInClosedRange

A protocol for types that can generate random values within a closed range using a RandomGenerator.

Int.random(in: -100 ... 100, using: &randomGenerator) // -79

RandomToValue

A protocol for types that can generate random values from a base value to another

View on GitHub
GitHub Stars1.5k
CategoryDevelopment
Updated5d ago
Forks90

Languages

Swift

Security Score

85/100

Audited on Mar 16, 2026

No findings