Repository: vapor/vapor
File: Sources/Vapor/Security/OTP.swift (Swift)

Code before:
///     let key = SymmetricKey(size: .bits128)
///     let code = HOTP.SHA1(key: key).generate(counter: 0)
///     print(code) "208503"
///
/// See `TOTP` for time-based one-time passwords.
public struct HOTP: OTP {
    let key: SymmetricKey
    let digits: OTPDigits
    let digest: OTPDigest
    
    /// Initialize the HOTP object.
    /// - Parameters:
    ///   - key: The key.
    ///   - digits: The number of digits to generate.
    fileprivate init(key: SymmetricKey, digits: OTPDigits, digest: OTPDigest) {
        self.key = key
        self.digits = digits
        self.digest = digest
    }
    
    /// SHA-1 digest based HOTP.
    /// - Parameters:
    ///   - key: The key.
    ///   - digits: The number of digits to generate.
    /// - Returns: The HOTP object.
    public static func SHA1(key: SymmetricKey, digits: OTPDigits = .six) -> Self {
        HOTP(key: key, digits: digits, digest: .sha1)
    }
    
    /// SHA-256 digest based HOTP.
    /// - Parameters:
    ///   - key: The key.
    ///   - digits: The number of digits to generate.
    /// - Returns: The HOTP object.
    public static func SHA256(key: SymmetricKey, digits: OTPDigits = .six) -> Self {
        HOTP(key: key, digits: digits, digest: .sha256)
    }
    
    /// SHA-512 digest based HOTP.
    /// - Parameters:
    ///   - key: The key.
    ///   - digits: The number of digits to generate.
    /// - Returns: The HOTP object.
    public static func SHA512(key: SymmetricKey, digits: OTPDigits = .six) -> Self {
        HOTP(key: key, digits: digits, digest: .sha512)
    }
    
    /// Generate the HOTP based on the counter.
    /// - Parameter counter: The counter to generate the HOTP for.
    /// - Returns: The generated HOTP as `String`.
    public func generate(counter: UInt64) -> String {

Review comment (suggestion):
These should probably be lower-case since they are not type names. 

```swift
let hotp = HOTP.sha1(key:digits:)
```

Code after:
        range: Int,
        size: Int = 1
    ) -> [String] {
        switch self.digest {
        case .sha1: return generateOTPs(Insecure.SHA1(), counter: counter, range: range, size: size)
        case .sha256: return generateOTPs(SHA256(), counter: counter, range: range, size: size)
        case .sha512: return generateOTPs(SHA512(), counter: counter, range: range, size: size)
        }
    }
}

/// Create a one-time password using hash-based message authentication codes.
///
///     let key = SymmetricKey(size: .bits128)
///     let code = HOTP.SHA1(key: key).generate(counter: 0)
///     print(code) "208503"
///
/// See `TOTP` for time-based one-time passwords.
public struct HOTP: OTP {
    let key: SymmetricKey
    let digits: OTPDigits
    let digest: OTPDigest
    
    /// Initialize the HOTP object.
    /// - Parameters:
    ///   - key: The key.
    ///   - digest: The digest to use.
    ///   - digits: The number of digits to generate.
    public init(
        key: SymmetricKey,
        digest: OTPDigest,
        digits: OTPDigits = .six
    ) {
        self.key = key
        self.digits = digits
        self.digest = digest
    }
    
    /// Generate the HOTP based on the counter.
    /// - Parameter counter: The counter to generate the HOTP for.
    /// - Returns: The generated HOTP as `String`.
    public func generate(
        counter: UInt64
    ) -> String {
        _generate(counter: counter)
    }
    
    /// Generates several HOTP's for a range.
    /// - Note: This function will automatically wrap the counter by using integer overflow.
    /// - Parameters:
    ///   - counter: The 'main' counter.