示例#1
0
        public void Should_match_test_vectors(string message, ulong seed, string expected)
        {
            var data = Encoding.UTF8.GetBytes(message);

            var result = WyHash64.ComputeHash64(data, seed);
            var actual = $"{result:x}";

            actual.ShouldBe(expected);
        }
示例#2
0
        public void Should_hash_data(int count, string expected)
        {
            // ReSharper disable once BuiltInTypeReferenceStyle
            var message = new String('a', count);
            var data    = Encoding.UTF8.GetBytes(message);

            var result = WyHash64.ComputeHash64(data, 42);
            var actual = $"{result:x}";

            actual.ShouldBe(expected);
        }
示例#3
0
        private static ulong GetCacheKey(IDictionary <string, object> hash)
        {
            var sb = new StringBuilder();

            foreach (var item in hash.StableOrder(x => x.Key))
            {
                sb.Append(item.Key);
                sb.Append('_');
                sb.Append((item.Value?.GetType() ?? typeof(object)).FullName);
            }

            return(WyHash64.ComputeHash64(sb.ToString(), 37731)); /* B3773rAP1 */
        }
        public override void OnActionExecuting(ActionExecutingContext context)
        {
            var seed = _cache.GetSeed();

            var privateAddress = typeof(IPAddress)
                                 .GetProperty("PrivateAddress", BindingFlags.Instance | BindingFlags.NonPublic)?
                                 .GetValue(context.HttpContext.Connection.RemoteIpAddress);

            if (privateAddress != default)
            {
                unsafe
                {
                    var address      = (uint)privateAddress;
                    var addressBytes = stackalloc byte[4];
                    addressBytes[0] = (byte)address;
                    addressBytes[1] = (byte)(address >> 8);
                    addressBytes[2] = (byte)(address >> 16);
                    addressBytes[3] = (byte)(address >> 24);

                    var hash = BitConverter.GetBytes(WyHash64.ComputeHash64(new ReadOnlySpan <byte>(addressBytes, 4),
                                                                            seed));
                    context.ActionArguments["addressHash"] = hash;
                }
            }
            else
            {
                privateAddress = typeof(IPAddress).GetField("_numbers", BindingFlags.Instance | BindingFlags.NonPublic)?
                                 .GetValue(context.HttpContext.Connection.RemoteIpAddress);

                if (privateAddress != default)
                {
                    unsafe
                    {
                        var address      = (ushort[])privateAddress;
                        var addressBytes = stackalloc byte[16];
                        var j            = 0;
                        for (var i = 0; i < 8; i++)
                        {
                            addressBytes[j++] = (byte)((address[i] >> 8) & 0xFF);
                            addressBytes[j++] = (byte)(address[i] & 0xFF);
                        }

                        var hash = BitConverter.GetBytes(
                            WyHash64.ComputeHash64(new ReadOnlySpan <byte>(addressBytes, 16), seed));
                        context.ActionArguments["addressHash"] = hash;
                    }
                }
            }

            base.OnActionExecuting(context);
        }
示例#5
0
        public void Different_overloads_returns_the_same(int length, int randomSeed)
        {
            var rand = new Random(randomSeed);
            var data = new byte[length];

            rand.NextBytes(data);

            Assert.Equal(WyHash64.ComputeHash64(data), WyHash64.ComputeHash64(data.AsSpan()));

            var         hashAlgorithm = WyHash64.Create();
            Span <byte> hashBlock     = stackalloc byte[hashAlgorithm.HashSize / 8];

            hashAlgorithm.TryComputeHash(data.AsSpan(), hashBlock, out int bytesWritten);
            Assert.Equal(hashBlock.Length, hashBlock.Length);
            Assert.Equal(BinaryPrimitives.ReadUInt64LittleEndian(hashBlock), WyHash64.ComputeHash64(data, 0));
        }
        public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
        {
            // FIXME: we do not want any allocations here, and could use reflection to pull PrivateAddress/_numbers
            var hash     = context.HttpContext.Connection.RemoteIpAddress?.GetAddressBytes();
            var cacheKey = WyHash64.ComputeHash64(hash, Seed);

            var now        = DateTimeOffset.UtcNow;
            var retryAfter = now.Add(_retryAfterDuration);

            if (_cache.Get <int>(cacheKey) == 0)
            {
                _cache.Set(cacheKey, 1, retryAfter);
                await next();
            }
            else
            {
                TooManyRequests(context, retryAfter);
            }
        }
示例#7
0
        private static string PrepareBodyFromTemplate(string template, dynamic hash)
        {
            string htmlBody = null;

            if (!string.IsNullOrWhiteSpace(template))
            {
                var      cacheKey = WyHash64.ComputeHash64(template);
                Template htmlTemplate;
                if (Compiled.ContainsKey(cacheKey))
                {
                    htmlTemplate = Compiled[cacheKey];
                }
                else
                {
                    htmlTemplate = Template.Parse(template);
                    Compiled.Add(cacheKey, htmlTemplate);
                }

                htmlBody = htmlTemplate.Render(hash);
            }

            return(htmlBody);
        }
示例#8
0
 public ulong ComputeHash64(ReadOnlySpan <byte> buffer, ulong seed)
 {
     return(WyHash64.ComputeHash64(buffer, seed));
 }
示例#9
0
 /// <summary>
 /// Create a hash key for a dictionary.
 ///     <remarks>
 ///         WyHash was chosen due to speed and performance with small keys (i.e. for use in a hash table)
 ///     </remarks>
 ///     <seealso href="https://github.com/rurban/smhasher/" />
 /// </summary>
 /// <param name="value"></param>
 /// <returns></returns>
 public static ulong Key(ReadOnlySpan <byte> value)
 {
     return(WyHash64.ComputeHash64(value, Seed));
 }
示例#10
0
 public void TestWyHash()
 {
     var result = WyHash64.ComputeHash64(this.data, Seed);
 }
        public static bool TryBuildFeedAsync <T>(string url, string ns, ulong rs, IEnumerable <T> records,
                                                 string mediaType, Encoding encoding, out byte[] stream, out DateTimeOffset?lastModified)
            where T : IRecord <T>
        {
            // FIXME: need to normalize this to produce stable IDs (i.e. when query strings are in a different order)
            var id = WyHash64.ComputeHash64(Encoding.UTF8.GetBytes(url),
                                            BitConverter.ToUInt64(Encoding.UTF8.GetBytes(nameof(SyndicationFeed))));

            var items = new List <SyndicationItem>();

            lastModified = default;
            foreach (var record in records)
            {
                var title       = $"{typeof(T).Name}";
                var description = $"Location of the {typeof(T).Name} record at the specified feed item URI";
                var uri         = $"/api/{ns}/v{rs}/{typeof(T).Name}/{record.Uuid}";

                var timestamp = TimestampFactory.FromUInt64(record.TimestampV2);
                var item      = new SyndicationItem(title, description, new Uri(uri, UriKind.Relative), title, timestamp);
                items.Add(item);
                lastModified = timestamp;
            }

            var feed = new SyndicationFeed($"{typeof(T).Name} Query Feed",
                                           $"A feed containing {typeof(T).Name} records for the query specified by the feed URI'", new Uri(url),
                                           $"{id}", lastModified.GetValueOrDefault(DateTimeOffset.Now))
            {
                Items = items
            };

            var settings = new XmlWriterSettings
            {
                Encoding            = encoding,
                NewLineHandling     = NewLineHandling.Entitize,
                NewLineOnAttributes = false,
                Indent = true
            };

            SyndicationFeedFormatter formatter;

            switch (mediaType)
            {
            case Constants.MediaTypeNames.Application.RssXml:
            case Constants.MediaTypeNames.Text.Xml:
            {
                formatter = new Rss20FeedFormatter(feed, false);
                break;
            }

            case Constants.MediaTypeNames.Application.AtomXml:
            {
                formatter = new Atom10FeedFormatter(feed);
                break;
            }

            default:
            {
                stream = default;
                return(false);
            }
            }

            using var ms     = new MemoryStream();
            using var writer = XmlWriter.Create(ms, settings);
            formatter.WriteTo(writer);
            writer.Flush();

            stream = ms.ToArray();
            return(true);
        }
示例#12
0
        public static string StrongETag <TRegion>(this byte[] data, ICacheRegion <TRegion> cache)
        {
            var value = WyHash64.ComputeHash64(data, cache.GetSeed());

            return($"\"{value}\"");
        }
示例#13
0
        public static string WeakETag <TRegion>(this string key, bool prefix, ICacheRegion <TRegion> cache)
        {
            var value = WyHash64.ComputeHash64(Encoding.UTF8.GetBytes(key), cache.GetSeed());

            return(prefix ? $"W/\"{value}\"" : $"\"{value}\"");
        }