All Projects → nvzqz → Randomkit

nvzqz / Randomkit

Licence: other
Random data generation in Swift

Programming Languages

swift
15916 projects

Projects that are alternatives of or similar to Randomkit

Guitar
A Cross-Platform String and Regular Expression Library written in Swift.
Stars: ✭ 641 (-56.04%)
Mutual labels:  cross-platform, watchos, cocoapods, carthage, swift-package-manager
Coregpx
A library for parsing and creation of GPX location files. Purely Swift.
Stars: ✭ 132 (-90.95%)
Mutual labels:  watchos, cocoapods, carthage, swift-package-manager
L10n Swift
Localization of the application with ability to change language "on the fly" and support for plural form in any language.
Stars: ✭ 177 (-87.86%)
Mutual labels:  watchos, cocoapods, carthage, swift-package-manager
Cdmarkdownkit
An extensive Swift framework providing simple and customizable markdown parsing.
Stars: ✭ 158 (-89.16%)
Mutual labels:  watchos, cocoapods, carthage, swift-package-manager
Web3.swift
A pure swift Ethereum Web3 library
Stars: ✭ 295 (-79.77%)
Mutual labels:  watchos, cocoapods, carthage, swift-package-manager
Swiftlinkpreview
It makes a preview from an URL, grabbing all the information such as title, relevant texts and images.
Stars: ✭ 1,216 (-16.6%)
Mutual labels:  watchos, cocoapods, carthage, swift-package-manager
Ducttape
📦 KeyPath dynamicMemberLookup based syntax sugar for Swift.
Stars: ✭ 138 (-90.53%)
Mutual labels:  watchos, cocoapods, carthage, swift-package-manager
Swifterswift
A handy collection of more than 500 native Swift extensions to boost your productivity.
Stars: ✭ 10,706 (+634.29%)
Mutual labels:  watchos, cocoapods, carthage, swift-package-manager
Functionkit
A framework for functional types and operations designed to fit naturally into Swift.
Stars: ✭ 302 (-79.29%)
Mutual labels:  watchos, cocoapods, carthage, swift-package-manager
Swiftframeworktemplate
A template for new Swift iOS / macOS / tvOS / watchOS Framework project ready with travis-ci, cocoapods, Carthage, SwiftPM and a Readme file
Stars: ✭ 527 (-63.85%)
Mutual labels:  watchos, cocoapods, carthage, swift-package-manager
Sketchkit
A lightweight auto-layout DSL library for iOS & tvOS.
Stars: ✭ 40 (-97.26%)
Mutual labels:  cocoapods, carthage, swift-package-manager
Fontblaster
Programmatically load custom fonts into your iOS and tvOS app.
Stars: ✭ 1,000 (-31.41%)
Mutual labels:  cocoapods, carthage, swift-package-manager
Sica
🦌 Simple Interface Core Animation. Run type-safe animation sequencially or parallelly
Stars: ✭ 980 (-32.78%)
Mutual labels:  cocoapods, carthage, swift-package-manager
Queuer
Queuer is a queue manager, built on top of OperationQueue and Dispatch (aka GCD).
Stars: ✭ 964 (-33.88%)
Mutual labels:  watchos, carthage, swift-package-manager
Sdwebimagewebpcoder
A WebP coder plugin for SDWebImage, use libwebp
Stars: ✭ 101 (-93.07%)
Mutual labels:  watchos, cocoapods, carthage
Wstagsfield
An iOS text field that represents tags, hashtags, tokens in general.
Stars: ✭ 1,013 (-30.52%)
Mutual labels:  cocoapods, carthage, swift-package-manager
Appz
📱 Launch external apps, and deeplink, with ease using Swift!
Stars: ✭ 1,092 (-25.1%)
Mutual labels:  watchos, cocoapods, carthage
Loadingshimmer
An easy way to add a shimmering effect to any view with just one line of code. It is useful as an unobtrusive loading indicator.
Stars: ✭ 1,180 (-19.07%)
Mutual labels:  cocoapods, carthage, swift-package-manager
Notificationz
📡 Helping you own NotificationCenter in Swift!
Stars: ✭ 74 (-94.92%)
Mutual labels:  watchos, cocoapods, carthage
Bfkit Swift
BFKit-Swift is a collection of useful classes, structs and extensions to develop Apps faster.
Stars: ✭ 963 (-33.95%)
Mutual labels:  cocoapods, carthage, swift-package-manager

RandomKit

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 value, noninclusive.

The base value for integers is 0. This means that calling random(to:using:) on a negative value will yield a random negative value or zero whereas a positive value will yield a random positive value or zero.

If value == randomBase, value will be returned for random(to:using:).

Int.random(to:  2, using: &randomGenerator)  // Either 0 or 1
Int.random(to:  0, using: &randomGenerator)  // Always 0
Int.random(to: 32, using: &randomGenerator)  // 15
Int.random(to: -5, using: &randomGenerator)  // -3

RandomThroughValue

A protocol for types that can generate random values from a base value through another value, inclusive.

The same rules regarding the base value of RandomToValue apply to RandomThroughValue.

RandomRetrievable

A protocol for types whose instances can have random elements retrieved.

["Bob", "Cindy", "May", "Charles", "Javier"].random(using: &randomGenerator)  // "Charles"

"Hello".characters.random(using: &randomGenerator)  // "e"

Some Foundation types like NSArray conform to this protocol.

RandomRetrievableInRange

A protocol for types whose instances can have random elements retrieved from within a Range<Index>.

[20, 37, 42].random(in: 1 ..< 3, using: &randomGenerator)  // Either 37 or 42

Shuffleable

A protocol for types whose elements can be shuffled.

// Array
[1, 2, 3, 4, 5].shuffled(using: &randomGenerator)  // [3, 4, 1, 5, 2]

// Dictionary
["a": 1, "b": 2, "c": 3].shuffled(using: &randomGenerator)  // ["a": 3, "b": 1, "c": 2]

The mutable counterpart of shuffled(using:) is shuffle(using:).

For better Array shuffling performance, consider shuffling in-place with shuffle(using:).

UniqueShuffleable

Similar to Shuffleable, except no element is ever in its initial position.

Swift Types

Integers

All of Swift's native integer types conform to the Random- protocols.

The random(using:) function creates an integer of any value. As a result, negative values can result for signed integers.

Int.random(using: &randomGenerator)               // An Int within Int.min and Int.max
Int.random(in: 10...20, using: &randomGenerator)  // An Int within 10 and 20

To create a positive signed integer, use random(to:using:) or random(through:using:).

Int.random(to: 1000, using: &randomGenerator)     // 731
Int.random(through: 10, using: &randomGenerator)  // 4

Signed integers can be created from any range, without danger of overflow.

Int.random(in: (.min + 1000)...(.max - 200), using: &randomGenerator)  // 5698527899712144154

Floating Point Numbers

Generate a random floating point value from within a range or 0.0...1.0 by default.

Double.random(using: &randomGenerator)                 //  0.9813615573117475
Double.random(in:  -10...10, using: &randomGenerator)  // -4.03042337718197
Float.random(in:   -10...10, using: &randomGenerator)  //  5.167088
Float80.random(in: -10...10, using: &randomGenerator)  // -3.63204542399198874

All FloatingPoint types can also conform to RandomInClosedRange out-of-the-box.

Bool

Bool.random(using:) has a 50/50 chance of being true.

If you need different probability, there's also random(withWeight:using:), which has 1 in weight chance of being true.

String, Character, and UnicodeScalar

String, Character, and UnicodeScalar generate values within " "..."~" by default.

String.random(ofLength: 10, using: &randomGenerator)                 // "}+[=Ng>$w1"
String.random(ofLength: 10, in: "A"..."z", using: &randomGenerator)  // "poUtXJIbv["

Character.random(using: &randomGenerator)                 // "#"
Character.random(in: "A"..."z", using: &randomGenerator)  // "s"

Arrays

An array of random values can be generated for types conforming to Random with init(randomCount:using:).

Similar initializers exist for all other Random- protocols.

let randoms = Array<Int>(randomCount: 100, using: &randomGenerator)  // [8845477344689834233, -957454203475087100, ...]

For types conforming to UnsafeRandom, a faster alternative is init(unsafeRandomCount:using:). This initializer fills the buffer directly rather than using random(using:).

let unsafeRandoms = Array<Int>(unsafeRandomCount: 100, using: &randomGenerator)  // [759709806207883991, 4618491969012429761, ...]
Arrays Benchmark

A benchmark of generating 1000 random Int arrays of 10000 count:

Generator Time (in seconds)
Xoroshiro 0.0271
Xorshift 0.0568
XorshiftStar 0.0319
ChaCha 0.2027
MersenneTwister 0.0432
ARC4Random 0.2416
DeviceRandom 5.3348

Note: Results may vary due to various factors.

This same benchmark can be run with:

./benchmark.sh --all-generators --array 10000 --count 1000

Foundation Types

Date

A random Date can be generated between two Date or TimeInterval values.

The default random(using:) function returns a Date within Date.distantPast and Date.distantFuture.

Date.random(using: &randomGenerator)  // "Aug 28, 2006, 3:38 AM"
Date.random(in: Date.distantPast...Date(), using: &randomGenerator)  // "Feb 7, 472, 5:40 AM"

Decimal

The Decimal type conforms to various Random- protocols.

The random(using:) function returns a Decimal between 0 and 1 by default.

Decimal.random(using: &randomGenerator)                  // 0.87490000409886706715888973957833129437
Decimal.random(in: 0.0...10.0, using: &randomGenerator)  // 6.5464639772070720738747790627821299859

NSNumber

A random number can be generated from within an integer or double range, or 0...100 by default.

NSNumber.random(using: &randomGenerator)                 // 79
NSNumber.random(in: -50...100, using: &randomGenerator)  // -27
NSNumber.random(in: 100...200, using: &randomGenerator)  // 149.6156950363926

Cocoa and UIKit Types

NSColor and UIColor

A random color can be generated, with or without random alpha.

NSColor.random(using: &randomGenerator)              // r 0.694 g 0.506 b 0.309 a 1.0
NSColor.random(alpha: true, using: &randomGenerator) // r 0.859 g 0.57  b 0.409 a 0.047

UIColor.random(using: &randomGenerator)              // r 0.488 g 0.805 b 0.679 a 1.0
UIColor.random(alpha: true, using: &randomGenerator) // r 0.444 g 0.121 b 0.602 a 0.085

CoreGraphics Types

CGFloat

Because CGFloat conforms to FloatingPoint, it conforms to RandomInClosedRange just like how Double and Float do.

CGFloat.random(using: &randomGenerator)               // 0.699803650379181
CGFloat.random(in: 0...100, using: &randomGenerator)  // 43.27969591675319

CGPoint

A random point can be generated from within ranges for x and y.

CGPoint.random(using: &randomGenerator) // {x 70.093 y 95.721}
CGPoint.random(xRange: 0...200, yRange: 0...10, using: &randomGenerator) // {x 73.795 y 0.991}

CGSize

A random size can be generated from within ranges for width and height.

CGSize.random(using: &randomGenerator) // {w 3.744  h 35.932}
CGSize.random(widthRange: 0...50, heightRange: 0...400, using: &randomGenerator) // {w 38.271 h 239.636}

CGRect

A random rectangle can be generated from within ranges for x, y, width, and height.

CGRect.random(using: &randomGenerator)  // {x 3.872  y 46.15  w 8.852  h 20.201}
CGRect.random(xRange: 0...50,
              yRange: 0...100,
              widthRange: 0...25,
              heightRange: 0...10,
              using: &randomGenerator)  // {x 13.212 y 79.147 w 20.656 h 5.663}

CGVector

A random vector can be generated from within ranges for dx and dy.

CGVector.random(using: &randomGenerator) // {dx 13.992 dy 89.376}
CGVector.random(dxRange: 0...50, dyRange: 0...10, using: &randomGenerator) // {dx 35.224 dy 13.463}

Extra

BigInt

RandomKit extensions for Károly's BigInt library are available in RandomKitBigInt.

License

RandomKit and its assets are released under the MIT License. Assets can be found in the assets branch.

Parts of this project utilize code written by Matt Gallagher and, in conjunction with the MIT License, are licensed with that found here.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].