• 源地址哈希算法


    using System.Collections.Generic;
    using System.Linq;
    using System.Security.Cryptography;
    using System.Text;
    
    namespace Console
    {
        class Program
        {
    
            static void Main(string[] args)
            {
                var ketAmaNodeLocator = new KetAmaHashingNodeLocator(new List<string> { "192.168.100.124:1442", "192.168.100.124:4555", "192.168.100.125:4444", "192.168.100.124:4477" });
                for (var i = 0; i < 100; i++)
                {
                    System.Console.WriteLine(ketAmaNodeLocator.GetPrimary($"154.244.100.{i}"));
                }
    
                System.Console.ReadLine();
            }
    
            /// <summary>
            /// KetAmaHashingNodeLocator
            /// </summary>
            public class KetAmaHashingNodeLocator
            {
    
                /// <summary>
                /// _ketAmaNodes
                /// </summary>
                private readonly SortedList<long, string> _ketAmaNodes;
    
                /// <summary>
                /// numReps
                /// </summary>
                private readonly int _numReps = 160;
    
                /// <summary>
                /// KetAmaHashingNodeLocator
                /// </summary>
                /// <param name="nodes">nodes</param>
                public KetAmaHashingNodeLocator(IEnumerable<string> nodes/*,int nodeCopies*/)
                {
                    _ketAmaNodes = new SortedList<long, string>();
                    //numReps = nodeCopies;
                    //对所有节点,生成nCopies个虚拟结点
                    foreach (var node in nodes)
                    {
                        //每四个虚拟结点为一组
                        for (var i = 0; i < _numReps / 4; i++)
                        {
                            //getKeyForNode方法为这组虚拟结点得到惟一名称 
                            var digest = HashAlgorithm.ComputeMd5(node + i);
                            /** Md5是一个16字节长度的数组,将16字节的数组每四个字节一组,分别对应一个虚拟结点,这就是为什么上面把虚拟结点四个划分一组的原因*/
                            for (var h = 0; h < 4; h++)
                            {
                                var m = HashAlgorithm.Hash(digest, h);
                                _ketAmaNodes[m] = node;
                            }
                        }
                    }
                }
    
                /// <summary>
                /// GetPrimary
                /// </summary>
                /// <param name="k">k</param>
                /// <returns>string</returns>
                public string GetPrimary(string k)
                {
                    var digest = HashAlgorithm.ComputeMd5(k);
                    var rv = GetNodeForKey(HashAlgorithm.Hash(digest, 0));
                    return rv;
                }
    
                /// <summary>
                /// GetNodeForKey
                /// </summary>
                /// <param name="hash">hash</param>
                /// <returns>string</returns>
                private string GetNodeForKey(long hash)
                {
                    var key = hash;
                    //如果找到这个节点,直接取节点,返回   
                    if (!_ketAmaNodes.ContainsKey(key))
                    {
                        var tailMap = (from coll in _ketAmaNodes
                                      where coll.Key > hash
                                      select new { coll.Key }).ToList();
                        key = !tailMap.Any() ? _ketAmaNodes.FirstOrDefault().Key : tailMap.First().Key;
                    }
                    var rv = _ketAmaNodes[key];
                    return rv;
                }
            }
    
            /// <summary>
            /// HashAlgorithm
            /// </summary>
            public class HashAlgorithm
            {
                /// <summary>
                /// Hash
                /// </summary>
                /// <param name="digest">digest</param>
                /// <param name="nTime">nTime</param>
                /// <returns>long</returns>
                public static long Hash(byte[] digest, int nTime)
                {
                    var rv = ((long)(digest[3 + nTime * 4] & 0xFF) << 24)
                            | ((long)(digest[2 + nTime * 4] & 0xFF) << 16)
                            | ((long)(digest[1 + nTime * 4] & 0xFF) << 8)
                            | ((long)digest[0 + nTime * 4] & 0xFF);
                    return rv & 0xffffffffL; /* Truncate to 32-bits */
                }
    
                /// <summary>
                /// Get the md5 of the given key.
                /// </summary>
                /// <param name="k">key</param>
                /// <returns>keyBytes</returns>
                public static byte[] ComputeMd5(string k)
                {
                    MD5 md5 = new MD5CryptoServiceProvider();
    
                    var keyBytes = md5.ComputeHash(Encoding.UTF8.GetBytes(k));
                    md5.Clear();
                    //md5.update(keyBytes);
                    //return md5.digest();
                    return keyBytes;
                }
            }
        }
    }

    参考github:https://github.com/jinyuttt/LoadBalanceHash

  • 相关阅读:
    JDK JRE Java虚拟机的关系
    apache和tomcat区别
    JBoss Web和 Tomcat的区别
    SOAP 与 restful service区别
    IntelliJ Idea 常用快捷键列表
    Win7用户文件夹转移
    相同IP和Mac地址的问题
    WebDriver 浅析
    Web UI 自动化测试
    python中xlrd模块的使用
  • 原文地址:https://www.cnblogs.com/liuxiaoji/p/10309710.html
Copyright © 2020-2023  润新知