refactor: split node agent and Go control plane
This commit is contained in:
@@ -0,0 +1,107 @@
|
||||
using System.Text;
|
||||
|
||||
namespace WxAgent.Core;
|
||||
|
||||
public sealed record WcdbKeyCandidate(string EncKey, string? SaltHint);
|
||||
|
||||
public sealed class WcdbKeyCandidateScanner
|
||||
{
|
||||
private const int KeyHexLength = 64;
|
||||
private const int SaltHexLength = 32;
|
||||
|
||||
private readonly StringBuilder _keyPrefix = new(KeyHexLength);
|
||||
private readonly char[] _saltSuffix = new char[SaltHexLength];
|
||||
private readonly HashSet<string> _seen = new(StringComparer.Ordinal);
|
||||
private long _runLength;
|
||||
private readonly bool _utf16;
|
||||
private bool _hasLowByte;
|
||||
private byte _lowByte;
|
||||
|
||||
public WcdbKeyCandidateScanner(bool utf16 = false) => _utf16 = utf16;
|
||||
|
||||
public IReadOnlyList<WcdbKeyCandidate> Feed(ReadOnlySpan<byte> bytes, bool finalBlock = false)
|
||||
{
|
||||
var found = new List<WcdbKeyCandidate>();
|
||||
foreach (var rawValue in bytes)
|
||||
{
|
||||
var value = rawValue;
|
||||
if (_utf16)
|
||||
{
|
||||
if (!_hasLowByte)
|
||||
{
|
||||
_lowByte = value;
|
||||
_hasLowByte = true;
|
||||
continue;
|
||||
}
|
||||
_hasLowByte = false;
|
||||
if (value != 0)
|
||||
{
|
||||
CompleteRun(found);
|
||||
continue;
|
||||
}
|
||||
value = _lowByte;
|
||||
}
|
||||
if (IsAsciiHex(value))
|
||||
{
|
||||
AppendHex(value);
|
||||
}
|
||||
else
|
||||
{
|
||||
CompleteRun(found);
|
||||
}
|
||||
}
|
||||
|
||||
if (finalBlock)
|
||||
{
|
||||
CompleteRun(found);
|
||||
_hasLowByte = false;
|
||||
}
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
private void AppendHex(byte value)
|
||||
{
|
||||
var character = char.ToLowerInvariant((char)value);
|
||||
if (_runLength < KeyHexLength)
|
||||
{
|
||||
_keyPrefix.Append(character);
|
||||
}
|
||||
|
||||
_saltSuffix[_runLength % SaltHexLength] = character;
|
||||
_runLength++;
|
||||
}
|
||||
|
||||
private void CompleteRun(List<WcdbKeyCandidate> found)
|
||||
{
|
||||
if (_runLength >= KeyHexLength)
|
||||
{
|
||||
var key = _keyPrefix.ToString();
|
||||
var salt = _runLength >= KeyHexLength + SaltHexLength ? GetSaltSuffix() : null;
|
||||
if (_seen.Add(key + ":" + salt))
|
||||
{
|
||||
found.Add(new WcdbKeyCandidate(key, salt));
|
||||
}
|
||||
}
|
||||
|
||||
_keyPrefix.Clear();
|
||||
_runLength = 0;
|
||||
}
|
||||
|
||||
private string GetSaltSuffix()
|
||||
{
|
||||
var salt = new char[SaltHexLength];
|
||||
var start = (int)(_runLength % SaltHexLength);
|
||||
for (var index = 0; index < salt.Length; index++)
|
||||
{
|
||||
salt[index] = _saltSuffix[(start + index) % SaltHexLength];
|
||||
}
|
||||
|
||||
return new string(salt);
|
||||
}
|
||||
|
||||
private static bool IsAsciiHex(byte value) =>
|
||||
value is >= (byte)'0' and <= (byte)'9' or
|
||||
>= (byte)'a' and <= (byte)'f' or
|
||||
>= (byte)'A' and <= (byte)'F';
|
||||
}
|
||||
Reference in New Issue
Block a user