diff --git a/.gitignore b/.gitignore
index dd53b36..aba7f56 100644
--- a/.gitignore
+++ b/.gitignore
@@ -194,3 +194,11 @@ FakesAssemblies/
# Visual Studio 6 workspace options file
*.opt
.vscode/
+.idea/.idea.Google.Authenticator/.idea/.name
+.idea/.idea.Google.Authenticator/.idea/codeStyles/codeStyleConfig.xml
+.idea/.idea.Google.Authenticator/.idea/encodings.xml
+.idea/.idea.Google.Authenticator/.idea/indexLayout.xml
+.idea/.idea.Google.Authenticator/.idea/projectSettingsUpdater.xml
+.idea/.idea.Google.Authenticator/.idea/vcs.xml
+.idea/.idea.Google.Authenticator/.idea/workspace.xml
+.idea/config/applicationhost.config
diff --git a/Google.Authenticator.Tests/AuthCodeTest.cs b/Google.Authenticator.Tests/AuthCodeTest.cs
index f2a3394..87f73f3 100644
--- a/Google.Authenticator.Tests/AuthCodeTest.cs
+++ b/Google.Authenticator.Tests/AuthCodeTest.cs
@@ -1,6 +1,6 @@
-using System;
-using Xunit;
+using System.Text;
using Shouldly;
+using Xunit;
namespace Google.Authenticator.Tests
{
@@ -9,17 +9,35 @@ public class AuthCodeTest
[Fact]
public void BasicAuthCodeTest()
{
- string secretKey = "PJWUMZKAUUFQKJBAMD6VGJ6RULFVW4ZH";
- string expected = "551508";
+ var secretKey = "PJWUMZKAUUFQKJBAMD6VGJ6RULFVW4ZH";
+ var expected = "551508";
+
+ var tfa = new TwoFactorAuthenticator();
- TwoFactorAuthenticator tfa = new TwoFactorAuthenticator();
-
- long currentTime = 1416643820;
+ var currentTime = 1416643820;
- // I actually think you are supposed to divide the time by 30 seconds? Maybe need an overload that takes a DateTime?
+ // I actually think you are supposed to divide the time by 30 seconds?
+ // Maybe need an overload that takes a DateTime?
var actual = tfa.GeneratePINAtInterval(secretKey, currentTime, 6);
- actual.ShouldBe(expected);
+ actual.ShouldBe(expected);
+ }
+
+ [Fact]
+ public void Base32AuthCodeTest()
+ {
+ var secretKey = Base32Encoding.ToString(Encoding.UTF8.GetBytes("PJWUMZKAUUFQKJBAMD6VGJ6RULFVW4ZH"));
+ var expected = "551508";
+
+ var tfa = new TwoFactorAuthenticator();
+
+ var currentTime = 1416643820;
+
+ // I actually think you are supposed to divide the time by 30 seconds?
+ // Maybe need an overload that takes a DateTime?
+ var actual = tfa.GeneratePINAtInterval(secretKey, currentTime, 6, true);
+
+ actual.ShouldBe(expected);
}
}
-}
+}
\ No newline at end of file
diff --git a/Google.Authenticator.Tests/Google.Authenticator.Tests.csproj b/Google.Authenticator.Tests/Google.Authenticator.Tests.csproj
index ee9e1b1..8ee17c7 100644
--- a/Google.Authenticator.Tests/Google.Authenticator.Tests.csproj
+++ b/Google.Authenticator.Tests/Google.Authenticator.Tests.csproj
@@ -1,21 +1,26 @@
- netcoreapp3.0;net452
+ netcoreapp3.0;net452;net5
false
-
+
-
-
-
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
-
-
+
\ No newline at end of file
diff --git a/Google.Authenticator.Tests/QRCodeTest.cs b/Google.Authenticator.Tests/QRCodeTest.cs
index c3bb3ae..7af20d1 100644
--- a/Google.Authenticator.Tests/QRCodeTest.cs
+++ b/Google.Authenticator.Tests/QRCodeTest.cs
@@ -1,4 +1,3 @@
-using System;
using Xunit;
using Shouldly;
@@ -10,7 +9,13 @@ public class QRCodeTest
public void CanGenerateQRCode()
{
var subject = new TwoFactorAuthenticator();
- var setupCodeInfo = subject.GenerateSetupCode("issuer","a@b.com","secret", false, 2);
+ var setupCodeInfo = subject.GenerateSetupCode(
+ "issuer",
+ "a@b.com",
+ "secret",
+ false,
+ 2);
+
setupCodeInfo.QrCodeSetupImageUrl.ShouldNotBeNull();
}
}
diff --git a/Google.Authenticator/Base32Encoding.cs b/Google.Authenticator/Base32Encoding.cs
index b9a6b23..0ea237f 100644
--- a/Google.Authenticator/Base32Encoding.cs
+++ b/Google.Authenticator/Base32Encoding.cs
@@ -16,41 +16,39 @@ public static byte[] ToBytes(string input)
{
if (string.IsNullOrEmpty(input))
{
- throw new ArgumentNullException("input");
+ throw new ArgumentNullException(nameof(input));
}
input = input.TrimEnd('='); //remove padding characters
- int byteCount = input.Length * 5 / 8; //this must be TRUNCATED
- byte[] returnArray = new byte[byteCount];
+ var byteCount = input.Length * 5 / 8; //this must be TRUNCATED
+ var returnArray = new byte[byteCount];
byte curByte = 0, bitsRemaining = 8;
- int mask = 0, arrayIndex = 0;
+ int mask, arrayIndex = 0;
- foreach (char c in input)
+ foreach (var c in input)
{
- int cValue = CharToValue(c);
+ var cValue = CharToValue(c);
if (bitsRemaining > 5)
{
mask = cValue << (bitsRemaining - 5);
- curByte = (byte)(curByte | mask);
+ curByte = (byte) (curByte | mask);
bitsRemaining -= 5;
}
else
{
mask = cValue >> (5 - bitsRemaining);
- curByte = (byte)(curByte | mask);
+ curByte = (byte) (curByte | mask);
returnArray[arrayIndex++] = curByte;
- curByte = (byte)(cValue << (3 + bitsRemaining));
+ curByte = (byte) (cValue << (3 + bitsRemaining));
bitsRemaining += 3;
}
}
//if we didn't end with a full byte
if (arrayIndex != byteCount)
- {
returnArray[arrayIndex] = curByte;
- }
return returnArray;
}
@@ -64,29 +62,29 @@ public static string ToString(byte[] input)
{
if (input == null || input.Length == 0)
{
- throw new ArgumentNullException("input");
+ throw new ArgumentNullException(nameof(input));
}
- int charCount = (int)Math.Ceiling(input.Length / 5d) * 8;
- char[] returnArray = new char[charCount];
+ var charCount = (int) Math.Ceiling(input.Length / 5d) * 8;
+ var returnArray = new char[charCount];
byte nextChar = 0, bitsRemaining = 5;
- int arrayIndex = 0;
+ var arrayIndex = 0;
- foreach (byte b in input)
+ foreach (var b in input)
{
- nextChar = (byte)(nextChar | (b >> (8 - bitsRemaining)));
+ nextChar = (byte) (nextChar | (b >> (8 - bitsRemaining)));
returnArray[arrayIndex++] = ValueToChar(nextChar);
if (bitsRemaining < 4)
{
- nextChar = (byte)((b >> (3 - bitsRemaining)) & 31);
+ nextChar = (byte) ((b >> (3 - bitsRemaining)) & 31);
returnArray[arrayIndex++] = ValueToChar(nextChar);
bitsRemaining += 5;
}
bitsRemaining -= 3;
- nextChar = (byte)((b << bitsRemaining) & 31);
+ nextChar = (byte) ((b << bitsRemaining) & 31);
}
//if we didn't end with a full char
@@ -101,41 +99,42 @@ public static string ToString(byte[] input)
private static int CharToValue(char c)
{
- int value = (int)c;
+ var value = (int) c;
//65-90 == uppercase letters
if (value < 91 && value > 64)
{
return value - 65;
}
+
//50-55 == numbers 2-7
if (value < 56 && value > 49)
{
return value - 24;
}
+
//97-122 == lowercase letters
if (value < 123 && value > 96)
{
return value - 97;
}
- throw new ArgumentException("Character is not a Base32 character.", "c");
+ throw new ArgumentException("Character is not a Base32 character.", nameof(c));
}
private static char ValueToChar(byte b)
{
if (b < 26)
{
- return (char)(b + 65);
+ return (char) (b + 65);
}
if (b < 32)
{
- return (char)(b + 24);
+ return (char) (b + 24);
}
- throw new ArgumentException("Byte is not a value Base32 value.", "b");
+ throw new ArgumentException("Byte is not a value Base32 value.", nameof(b));
}
-
}
}
\ No newline at end of file
diff --git a/Google.Authenticator/Google.Authenticator.csproj b/Google.Authenticator/Google.Authenticator.csproj
index a8d3ce2..2bbf2ea 100644
--- a/Google.Authenticator/Google.Authenticator.csproj
+++ b/Google.Authenticator/Google.Authenticator.csproj
@@ -1,20 +1,20 @@
- netstandard2.0;net45
+ netstandard2.0;net45;net5
Google Authenticator Two-Factor
Google Authenticator Two-Factor Authentication Library
Google Authenticator Two-Factor Authentication Library (Not officially affiliated with Google.)
Brandon Potter
Brandon Potter
- 2.1.1
+ 2.2.0
Apache-2.0
https://github.com/BrandonPotter/GoogleAuthenticator
GoogleAuthenticator
-
+
@@ -30,6 +30,10 @@
NET45;NETFULL
+
+ NET5_0;NETCOREAPP
+
+
$(AllowedOutputExtensionsInPackageBuildOutputFolder);.pdb
@@ -37,4 +41,4 @@
true
2.0.1.0
-
\ No newline at end of file
+
diff --git a/Google.Authenticator/SetupCode.cs b/Google.Authenticator/SetupCode.cs
index 657ccdf..7964d14 100644
--- a/Google.Authenticator/SetupCode.cs
+++ b/Google.Authenticator/SetupCode.cs
@@ -1,9 +1,4 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-
-namespace Google.Authenticator
+namespace Google.Authenticator
{
public class SetupCode
{
diff --git a/Google.Authenticator/TwoFactorAuthenticator.cs b/Google.Authenticator/TwoFactorAuthenticator.cs
index a76cc7d..b0a5ac5 100644
--- a/Google.Authenticator/TwoFactorAuthenticator.cs
+++ b/Google.Authenticator/TwoFactorAuthenticator.cs
@@ -1,7 +1,6 @@
using QRCoder;
using System;
using System.Collections.Generic;
-using System.Drawing;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
@@ -17,209 +16,237 @@ namespace Google.Authenticator
///
public class TwoFactorAuthenticator
{
- private readonly static DateTime _epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
+ private static readonly DateTime _epoch =
+ new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
+
private TimeSpan DefaultClockDriftTolerance { get; set; }
- public TwoFactorAuthenticator()
- {
- DefaultClockDriftTolerance = TimeSpan.FromMinutes(5);
- }
+ public TwoFactorAuthenticator() => DefaultClockDriftTolerance = TimeSpan.FromMinutes(5);
///
/// Generate a setup code for a Google Authenticator user to scan
///
- /// Issuer ID (the name of the system, i.e. 'MyApp'), can be omitted but not recommended https://github.com/google/google-authenticator/wiki/Key-Uri-Format
+ /// Issuer ID (the name of the system, i.e. 'MyApp'),
+ /// can be omitted but not recommended https://github.com/google/google-authenticator/wiki/Key-Uri-Format
+ ///
/// Account Title (no spaces)
/// Account Secret Key
/// Flag saying if accountSecretKey is in Base32 format or original secret
- /// Number of pixels per QR Module (2 pixels give ~ 100x100px QRCode, should be 10 or less)
+ /// Number of pixels per QR Module (2 pixels give ~ 100x100px QRCode,
+ /// should be 10 or less)
/// SetupCode object
- public SetupCode GenerateSetupCode(string issuer, string accountTitleNoSpaces, string accountSecretKey, bool secretIsBase32, int QRPixelsPerModule = 3)
+ public SetupCode GenerateSetupCode(
+ string issuer,
+ string accountTitleNoSpaces,
+ string accountSecretKey,
+ bool secretIsBase32,
+ int qrPixelsPerModule = 3)
{
- byte[] key = secretIsBase32 ? Base32Encoding.ToBytes(accountSecretKey) : Encoding.UTF8.GetBytes(accountSecretKey);
- return GenerateSetupCode(issuer, accountTitleNoSpaces, key, QRPixelsPerModule);
+ var key = secretIsBase32
+ ? Base32Encoding.ToBytes(accountSecretKey)
+ : Encoding.UTF8.GetBytes(accountSecretKey);
+
+ return GenerateSetupCode(issuer, accountTitleNoSpaces, key, qrPixelsPerModule);
}
///
/// Generate a setup code for a Google Authenticator user to scan
///
- /// Issuer ID (the name of the system, i.e. 'MyApp'), can be omitted but not recommended https://github.com/google/google-authenticator/wiki/Key-Uri-Format
+ /// Issuer ID (the name of the system, i.e. 'MyApp'), can be omitted but not
+ /// recommended https://github.com/google/google-authenticator/wiki/Key-Uri-Format
/// Account Title (no spaces)
/// Account Secret Key as byte[]
- /// Number of pixels per QR Module (2 = ~120x120px QRCode, should be 10 or less)
+ /// Number of pixels per QR Module
+ /// (2 = ~120x120px QRCode, should be 10 or less)
+ ///
/// SetupCode object
- public SetupCode GenerateSetupCode(string issuer, string accountTitleNoSpaces, byte[] accountSecretKey, int QRPixelsPerModule = 3, bool generateQrCode = true)
- {
- if (String.IsNullOrWhiteSpace(accountTitleNoSpaces)) { throw new NullReferenceException("Account Title is null"); }
- accountTitleNoSpaces = RemoveWhitespace(Uri.EscapeUriString(accountTitleNoSpaces));
- string encodedSecretKey = Base32Encoding.ToString(accountSecretKey);
- string provisionUrl;
- if (String.IsNullOrWhiteSpace(issuer))
+ public SetupCode GenerateSetupCode(
+ string issuer,
+ string accountTitleNoSpaces,
+ byte[] accountSecretKey,
+ int qrPixelsPerModule = 3,
+ bool generateQrCode = true)
+ {
+ if (string.IsNullOrWhiteSpace(accountTitleNoSpaces))
{
- provisionUrl = String.Format("otpauth://totp/{0}?secret={1}", accountTitleNoSpaces, encodedSecretKey.Trim('='));
+ throw new NullReferenceException("Account Title is null");
}
- else
- {
+
+ accountTitleNoSpaces = RemoveWhitespace(Uri.EscapeUriString(accountTitleNoSpaces));
+ var encodedSecretKey = Base32Encoding.ToString(accountSecretKey);
+
+ var provisionUrl = string.IsNullOrWhiteSpace(issuer)
+ ? $"otpauth://totp/{accountTitleNoSpaces}?secret={encodedSecretKey.Trim('=')}"
// https://github.com/google/google-authenticator/wiki/Conflicting-Accounts
- // Added additional prefix to account otpauth://totp/Company:joe_example@gmail.com for backwards compatibility
- provisionUrl = String.Format("otpauth://totp/{2}:{0}?secret={1}&issuer={2}", accountTitleNoSpaces, encodedSecretKey.Trim('='), UrlEncode(issuer));
- }
+ // Added additional prefix to account otpauth://totp/Company:joe_example@gmail.com
+ // for backwards compatibility
+ : $"otpauth://totp/{UrlEncode(issuer)}:{accountTitleNoSpaces}?secret={encodedSecretKey.Trim('=')}&issuer={UrlEncode(issuer)}";
- string qrCodeUrl = string.Empty;
- if (generateQrCode)
+ return new SetupCode(
+ accountTitleNoSpaces,
+ encodedSecretKey.Trim('='),
+ generateQrCode ? GenerateQrCodeUrl(qrPixelsPerModule, provisionUrl) : "");
+ }
+
+ private static string GenerateQrCodeUrl(int qrPixelsPerModule, string provisionUrl)
+ {
+ var qrCodeUrl = "";
+ try
{
- try
+ using (var qrGenerator = new QRCodeGenerator())
+ using (var qrCodeData = qrGenerator.CreateQrCode(provisionUrl, QRCodeGenerator.ECCLevel.Q))
+ using (var qrCode = new QRCode(qrCodeData))
+ using (var qrCodeImage = qrCode.GetGraphic(qrPixelsPerModule))
+ using (var ms = new MemoryStream())
{
- using (QRCodeGenerator qrGenerator = new QRCodeGenerator())
- using (QRCodeData qrCodeData = qrGenerator.CreateQrCode(provisionUrl, QRCodeGenerator.ECCLevel.Q))
- using (QRCode qrCode = new QRCode(qrCodeData))
- using (Bitmap qrCodeImage = qrCode.GetGraphic(QRPixelsPerModule))
- using (MemoryStream ms = new MemoryStream())
- {
- qrCodeImage.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
-
- qrCodeUrl = String.Format("data:image/png;base64,{0}", Convert.ToBase64String(ms.ToArray()));
- }
+ qrCodeImage.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
+ qrCodeUrl = $"data:image/png;base64,{Convert.ToBase64String(ms.ToArray())}";
}
- catch (System.TypeInitializationException e)
+ }
+ catch (TypeInitializationException e)
+ {
+ if (e.InnerException != null
+ && e.InnerException.GetType() == typeof(DllNotFoundException)
+ && e.InnerException.Message.Contains("libgdiplus"))
{
- if (e.InnerException != null
- && e.InnerException.GetType() == typeof(System.DllNotFoundException)
- && e.InnerException.Message.Contains("libgdiplus"))
- {
- throw new MissingDependencyException("It looks like libgdiplus has not been installed - see https://github.com/codebude/QRCoder/issues/227", e);
- }
+ throw new MissingDependencyException(
+ "It looks like libgdiplus has not been installed - see" +
+ " https://github.com/codebude/QRCoder/issues/227",
+ e);
}
- catch (System.Runtime.InteropServices.ExternalException e)
+ }
+ catch (System.Runtime.InteropServices.ExternalException e)
+ {
+ if (e.Message.Contains("GDI+") && qrPixelsPerModule > 10)
{
- if (e.Message.Contains("GDI+") && QRPixelsPerModule > 10)
- {
- throw new QRException($"There was a problem generating a QR code. The value of {nameof(QRPixelsPerModule)} should be set to a value of 10 or less for optimal results.", e);
- }
+ throw new QRException(
+ $"There was a problem generating a QR code. The value of {nameof(qrPixelsPerModule)}" +
+ " should be set to a value of 10 or less for optimal results.",
+ e);
}
}
- return new SetupCode(accountTitleNoSpaces, encodedSecretKey.Trim('='), qrCodeUrl);
+ return qrCodeUrl;
}
- private static string RemoveWhitespace(string str)
- {
- return new string(str.Where(c => !Char.IsWhiteSpace(c)).ToArray());
- }
+ private static string RemoveWhitespace(string str) =>
+ new string(str.Where(c => !char.IsWhiteSpace(c)).ToArray());
private string UrlEncode(string value)
{
- StringBuilder result = new StringBuilder();
- string validChars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_.~";
+ var result = new StringBuilder();
+ var validChars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_.~";
- foreach (char symbol in value)
+ foreach (var symbol in value)
{
- if (validChars.IndexOf(symbol) != -1)
+ if (validChars.IndexOf(symbol) == -1)
{
- result.Append(symbol);
+ result.AppendFormat("%{0:X2}", (int) symbol);
}
else
{
- result.Append('%' + String.Format("{0:X2}", (int)symbol));
+ result.Append(symbol);
}
}
- return result.ToString().Replace(" ", "%20");
+ return result.Replace(" ", "%20").ToString();
}
- public string GeneratePINAtInterval(string accountSecretKey, long counter, int digits = 6)
+ public string GeneratePINAtInterval(
+ string accountSecretKey,
+ long counter,
+ int digits = 6,
+ bool secretIsBase32 = false)
{
- return GenerateHashedCode(accountSecretKey, counter, digits);
+ return GenerateHashedCode(accountSecretKey, counter, secretIsBase32, digits);
}
- internal string GenerateHashedCode(string secret, long iterationNumber, int digits = 6)
+ private string GenerateHashedCode(string secret,
+ long iterationNumber,
+ bool secretIsBase32,
+ int digits = 6)
{
- byte[] key = Encoding.UTF8.GetBytes(secret);
- return GenerateHashedCode(key, iterationNumber, digits);
+ return GenerateHashedCode(
+ secretIsBase32 ? Base32Encoding.ToBytes(secret) : Encoding.UTF8.GetBytes(secret),
+ iterationNumber,
+ digits);
}
- internal string GenerateHashedCode(byte[] key, long iterationNumber, int digits = 6)
+ private string GenerateHashedCode(byte[] key, long iterationNumber, int digits = 6)
{
- byte[] counter = BitConverter.GetBytes(iterationNumber);
+ var counter = BitConverter.GetBytes(iterationNumber);
if (BitConverter.IsLittleEndian)
- {
Array.Reverse(counter);
- }
-
- HMACSHA1 hmac = new HMACSHA1(key);
- byte[] hash = hmac.ComputeHash(counter);
-
- int offset = hash[hash.Length - 1] & 0xf;
+ var hmac = new HMACSHA1(key);
+ var hash = hmac.ComputeHash(counter);
+ var offset = hash[hash.Length - 1] & 0xf;
// Convert the 4 bytes into an integer, ignoring the sign.
- int binary =
+ var binary =
((hash[offset] & 0x7f) << 24)
| (hash[offset + 1] << 16)
| (hash[offset + 2] << 8)
- | (hash[offset + 3]);
+ | hash[offset + 3];
- int password = binary % (int)Math.Pow(10, digits);
+ var password = binary % (int) Math.Pow(10, digits);
return password.ToString(new string('0', digits));
}
- private long GetCurrentCounter()
- {
- return GetCurrentCounter(DateTime.UtcNow, _epoch, 30);
- }
+ private long GetCurrentCounter() => GetCurrentCounter(DateTime.UtcNow, _epoch, 30);
- private long GetCurrentCounter(DateTime now, DateTime epoch, int timeStep)
- {
- return (long)(now - epoch).TotalSeconds / timeStep;
- }
+ private long GetCurrentCounter(DateTime now, DateTime epoch, int timeStep) =>
+ (long) (now - epoch).TotalSeconds / timeStep;
- public bool ValidateTwoFactorPIN(string accountSecretKey, string twoFactorCodeFromClient)
+ public bool ValidateTwoFactorPIN(
+ string accountSecretKey,
+ string twoFactorCodeFromClient,
+ bool secretIsBase32 = false)
{
- return ValidateTwoFactorPIN(accountSecretKey, twoFactorCodeFromClient, DefaultClockDriftTolerance);
+ return ValidateTwoFactorPIN(accountSecretKey, twoFactorCodeFromClient, DefaultClockDriftTolerance,
+ secretIsBase32);
}
- public bool ValidateTwoFactorPIN(string accountSecretKey, string twoFactorCodeFromClient, TimeSpan timeTolerance)
+ public bool ValidateTwoFactorPIN(
+ string accountSecretKey,
+ string twoFactorCodeFromClient,
+ TimeSpan timeTolerance,
+ bool secretIsBase32 = false)
{
- var codes = GetCurrentPINs(accountSecretKey, timeTolerance);
- return codes.Any(c => c == twoFactorCodeFromClient);
+ return GetCurrentPINs(accountSecretKey, timeTolerance, secretIsBase32)
+ .Any(c => c == twoFactorCodeFromClient);
}
- public string GetCurrentPIN(string accountSecretKey)
- {
- return GeneratePINAtInterval(accountSecretKey, GetCurrentCounter());
- }
+ public string GetCurrentPIN(string accountSecretKey, bool secretIsBase32 = false) =>
+ GeneratePINAtInterval(accountSecretKey, GetCurrentCounter(), secretIsBase32: secretIsBase32);
- public string GetCurrentPIN(string accountSecretKey, DateTime now)
- {
- return GeneratePINAtInterval(accountSecretKey, GetCurrentCounter(now, _epoch, 30));
- }
+ public string GetCurrentPIN(string accountSecretKey, DateTime now, bool secretIsBase32 = false) =>
+ GeneratePINAtInterval(accountSecretKey, GetCurrentCounter(now, _epoch, 30));
- public string[] GetCurrentPINs(string accountSecretKey)
- {
- return GetCurrentPINs(accountSecretKey, DefaultClockDriftTolerance);
- }
+ public string[] GetCurrentPINs(string accountSecretKey, bool secretIsBase32 = false) =>
+ GetCurrentPINs(accountSecretKey, DefaultClockDriftTolerance, secretIsBase32);
- public string[] GetCurrentPINs(string accountSecretKey, TimeSpan timeTolerance)
+ public string[] GetCurrentPINs(string accountSecretKey, TimeSpan timeTolerance, bool secretIsBase32 = false)
{
- List codes = new List();
- long iterationCounter = GetCurrentCounter();
- int iterationOffset = 0;
+ var codes = new List();
+ var iterationCounter = GetCurrentCounter();
+ var iterationOffset = 0;
if (timeTolerance.TotalSeconds > 30)
{
iterationOffset = Convert.ToInt32(timeTolerance.TotalSeconds / 30.00);
}
- long iterationStart = iterationCounter - iterationOffset;
- long iterationEnd = iterationCounter + iterationOffset;
+ var iterationStart = iterationCounter - iterationOffset;
+ var iterationEnd = iterationCounter + iterationOffset;
- for (long counter = iterationStart; counter <= iterationEnd; counter++)
+ for (var counter = iterationStart; counter <= iterationEnd; counter++)
{
- codes.Add(GeneratePINAtInterval(accountSecretKey, counter));
+ codes.Add(GeneratePINAtInterval(accountSecretKey, counter, secretIsBase32: secretIsBase32));
}
return codes.ToArray();
}
}
-}
+}
\ No newline at end of file