示例#1
0
        /// <summary>
        /// Generates several raw codes. This is used to account for counter drift across 2 generators.
        /// </summary>
        /// <param name="window">
        /// Number of additional codes to generate in each direction. For example, a value of 2 will generate 5 codes:
        /// 2 after the current value, 2 before, and one for current value. Non-positive value will use defaults of 1
        /// for TOTP, and 2 for HOTP.
        /// </param>
        /// <param name="groupSize">Optional. Maximum number of digits per digit group.</param>
        /// <returns>Enumerable of generated codes.</returns>
        public IEnumerable <string> GenerateWindow(int window = 0, int groupSize = 0)
        {
            if (window == 0)
            {
                window = this.Settings.Type switch
                {
                    ChallengeType.Time => 1,
                    ChallengeType.Counter => 2,
                    _ => 0
                }
            }
            ;

            var ctr = this.Settings.GetCounterValue();

            for (var i = ctr - window; i <= ctr + window; i++)
            {
                var number = this.GenerateNumber(value: i);

                if (groupSize > 0)
                {
                    yield return(StringCodeFormatter.FormatGroupped(number, this.Settings.Digits, groupSize));
                }
                else
                {
                    yield return(StringCodeFormatter.Format(number, this.Settings.Digits));
                }
            }
        }
示例#2
0
        /// <summary>
        /// Generates one-time password.
        /// </summary>
        /// <param name="groupSize">Optional. Maximum number of digits per digit group.</param>
        /// <param name="offset">Counter offset to use when generating.</param>
        /// <returns>Generated password.</returns>
        public string Generate(int groupSize = 0, int offset = 0)
        {
            var number = this.GenerateNumber(offset);

            if (groupSize > 0)
            {
                return(StringCodeFormatter.FormatGroupped(number, this.Settings.Digits, groupSize));
            }
            else
            {
                return(StringCodeFormatter.Format(number, this.Settings.Digits));
            }
        }
示例#3
0
        /// <summary>
        /// Generates one-time password.
        /// </summary>
        /// <param name="output">Buffer to place the generated password characters in.</param>
        /// <param name="groupSize">Optional. Maximum number of digits per digit group.</param>
        /// <param name="offset">Counter offset to use when generating.</param>
        /// <returns>Whether the operation was successful.</returns>
        public bool TryGenerate(Span <char> output, int groupSize = 0, int offset = 0)
        {
            if (!this.TryGenerateNumber(offset, out var number))
            {
                return(false);
            }

            if (groupSize > 0)
            {
                return(StringCodeFormatter.TryFormatGroupped(number, this.Settings.Digits, output, groupSize));
            }
            else
            {
                return(StringCodeFormatter.TryFormat(number, this.Settings.Digits, output));
            }
        }
示例#4
0
        /// <summary>
        /// Generates raw, numeric one-time password.
        /// </summary>
        /// <param name="offset">Counter offset to use when generating.</param>
        /// <returns>Generated password.</returns>
        public int GenerateRaw(int offset = 0)
        {
            var number = this.GenerateNumber(offset);

            return(StringCodeFormatter.GetRawCode(number, this.Settings.Digits));
        }