Better session ID generation code.
This commit is contained in:
parent
8050a295c1
commit
dbdaaeec9e
3 changed files with 60 additions and 24 deletions
|
@ -4,7 +4,7 @@ using System.Collections.Generic;
|
|||
using System.Net;
|
||||
|
||||
namespace SharpChat {
|
||||
public class ChatUserSession : IDisposable, IPacketTarget {
|
||||
public class ChatUserSession : IDisposable {
|
||||
public const int ID_LENGTH = 32;
|
||||
|
||||
#if DEBUG
|
||||
|
@ -22,9 +22,6 @@ namespace SharpChat {
|
|||
|
||||
private int CloseCode { get; set; } = 1000;
|
||||
|
||||
public string TargetName => "@log";
|
||||
|
||||
|
||||
private IPAddress _RemoteAddress = null;
|
||||
|
||||
public IPAddress RemoteAddress {
|
||||
|
@ -44,13 +41,7 @@ namespace SharpChat {
|
|||
|
||||
public ChatUserSession(IWebSocketConnection ws) {
|
||||
Connection = ws;
|
||||
Id = GenerateId();
|
||||
}
|
||||
|
||||
private static string GenerateId() {
|
||||
byte[] buffer = new byte[ID_LENGTH];
|
||||
RNG.NextBytes(buffer);
|
||||
return buffer.GetIdString();
|
||||
Id = RNG.SecureRandomString(ID_LENGTH);
|
||||
}
|
||||
|
||||
public void Send(IServerPacket packet) {
|
||||
|
|
|
@ -1,13 +0,0 @@
|
|||
using System.Text;
|
||||
|
||||
namespace SharpChat {
|
||||
public static class Extensions {
|
||||
public static string GetIdString(this byte[] buffer) {
|
||||
const string id_chars = "abcdefghijklmnopqrstuvwxyz0123456789-_ABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
||||
StringBuilder sb = new();
|
||||
foreach(byte b in buffer)
|
||||
sb.Append(id_chars[b % id_chars.Length]);
|
||||
return sb.ToString();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,8 +1,11 @@
|
|||
using System;
|
||||
using System.Buffers;
|
||||
using System.Security.Cryptography;
|
||||
|
||||
namespace SharpChat {
|
||||
public static class RNG {
|
||||
public const string CHARS = "AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz0123456789";
|
||||
|
||||
private static Random NormalRandom { get; } = new();
|
||||
private static RandomNumberGenerator SecureRandom { get; } = RandomNumberGenerator.Create();
|
||||
|
||||
|
@ -21,5 +24,60 @@ namespace SharpChat {
|
|||
public static void NextBytes(byte[] buffer) {
|
||||
SecureRandom.GetBytes(buffer);
|
||||
}
|
||||
|
||||
public static int SecureNext() {
|
||||
return SecureNext(int.MaxValue);
|
||||
}
|
||||
|
||||
public static int SecureNext(int max) {
|
||||
return SecureNext(0, max);
|
||||
}
|
||||
|
||||
public static int SecureNext(int min, int max) {
|
||||
--max;
|
||||
if(min == max)
|
||||
return min;
|
||||
|
||||
uint umax = (uint)max - (uint)min;
|
||||
uint num;
|
||||
|
||||
byte[] buffer = ArrayPool<byte>.Shared.Rent(4);
|
||||
try {
|
||||
SecureRandom.GetBytes(buffer);
|
||||
num = BitConverter.ToUInt32(buffer);
|
||||
|
||||
if(umax != uint.MaxValue) {
|
||||
++umax;
|
||||
|
||||
if((umax & (umax - 1)) != 0) {
|
||||
uint limit = uint.MaxValue - (uint.MaxValue & umax) - 1;
|
||||
|
||||
while(num > limit) {
|
||||
SecureRandom.GetBytes(buffer);
|
||||
num = BitConverter.ToUInt32(buffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
ArrayPool<byte>.Shared.Return(buffer);
|
||||
}
|
||||
|
||||
return (int)((num % umax) + min);
|
||||
}
|
||||
|
||||
private static string RandomStringInternal(Func<int, int> next, int length) {
|
||||
char[] str = new char[length];
|
||||
for(int i = 0; i < length; ++i)
|
||||
str[i] = CHARS[next(CHARS.Length)];
|
||||
return new string(str);
|
||||
}
|
||||
|
||||
public static string RandomString(int length) {
|
||||
return RandomStringInternal(Next, length);
|
||||
}
|
||||
|
||||
public static string SecureRandomString(int length) {
|
||||
return RandomStringInternal(SecureNext, length);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue