C#,谷歌(Google)CityHash64与CityHash128散列哈希算法的C#源程序

news2025/1/16 15:41:37

1、CityHash简史

Google 2011年发布了 CityHash 系列字符串散列算法 。今天发布的有两种算法:CityHash64 与 CityHash128 。它们分别根据字串计算 64 和 128 位的散列值。这些算法不适用于加密,但适合用在散列表等处。 

Google 一直在根据其数据中心常用的 CPU  对算法进行优化,结果发现对大多数个人计算机与笔记本同样有效益。尤其是在 64 位寄存器、指令集级的并行,以及快速非对其内存存取方面。

该算法的开发受到了前人在散列算法方面的巨大启发,尤其是 Austin Appleby 的 MurmurHash 。但 CityHash 的主要优点是大部分步骤包含了至少两步独立的数学运算。现代 CPU 通常能从这种代码获得最佳性能。

但 CityHash 也有其缺点:代码较同类流行算法复杂。Google 希望为速度而不是为了简单而优化,因此没有照顾较短输入的特例。

总体而言,CityHash64 与 CityHash128 是解决经典问题的全新算法。在实际应用中,Google 预计 CityHash64 在速度方面至少能提高30% ,并有望提高多达两倍 。此外,这些算法的统计特性也很完备。

 

2、CityHash介绍(字符串的哈希函数家族)

CityHash为字符串提供哈希函数。这些功能混合了彻底地输入比特,但不适用于密码学。看见下面的“哈希质量”,了解有关CityHash如何测试等的详细信息。
我们提供了C++中的参考实现,并提供了友好的MIT许可证。
CityHash32()返回32位哈希。
CityHash64()和类似的函数返回64位哈希。
CityHash128()和类似的函数返回128位哈希,并针对至少几百字节的字符串。取决于编译器在足够长的时间内,它可能比CityHash64()更快串。在较短的字符串上,它比所需的要慢,但我们预计这种情况相对来说并不重要。
CityHashCrc128()和类似的是CityHash128()的变体在_mm_crc32_u64()上,编译为crc32指令的内部函数在一些CPU上。然而,我们提供的功能都不是CRC。
CityHashCrc256()是CityHashCrc128()的变体在_mm_crc32_u64()上。它返回256位哈希。
CityHash家族的所有成员在设计时都非常依赖奥斯汀·阿普比、鲍勃·詹金斯和其他人之前的工作。
例如,CityHash32与Murmur3a有许多相似之处。


长字符串性能:64位CPU

CityHash64()及其变体在短字符串,但长字符串也很有趣。
CityHash的目标是快速,但它的哈希非常好对于具有CRC32指令的CPU,CRC是快速的,但CRC不是设计为哈希函数,不应作为一个函数使用。CityHashCrc128()不是CRC,但它使用CRC32机制。
在2.67GHz Intel Xeon X5550的单核上,CityHashCrc256的峰值约为5至5.5字节/周期。其他CityHashCrc函数是包装器CityHashCrc256和应该在长字符串上具有类似的性能。(v1.0.3中的CityHashCrc256甚至更快,但我们认为它不够彻底CityHash128的峰值约为4.3字节/周期。最快的该硬件上的Murmur变体Murmur3F的峰值约为2.4字节/周期。
我们预计CityHash128的峰值速度将主导CityHash64更倾向于短字符串或在哈希表中使用。
对于长字符串,Bob Jenkins的一个新函数SpookyHash只是在Intel x86-64 CPU上比CityHash128稍慢,但明显在AMD x86-64 CPU上速度更快。用于在AMD CPU上哈希长字符串和/或没有CRC指令的CPU,SpookyHash可能与比任何CityHash变体都好或更好。


短字符串性能:64位CPU

对于短字符串,例如大多数哈希表键,CityHash64比CityHash128,这取决于串长度的混合。这里有一些结果同样的硬件,我们(不切实际地)在再次:

哈希结果

CityHash64 v1.0.3 7ns表示1字节,或6ns表示8字节,或9ns表示64字节Murmur2(64位)6ns表示1字节,或6ns表示8字节,或15ns表示64字节1字节为14ns,8字节为15ns,64字节为23ns我们没有1.1版的CityHash64基准测试结果,但我们希望数字相似。

性能:32位CPU

CityHash32是CityHash的最新变体。其目的是通常是32位硬件,但主要是在x86上测试的。我们的基准暗示Murmur3是x86上CityHash32最接近的竞争对手。
我们不知道有什么速度更快的产品质量可以媲美。速度排名在我们的测试中:CityHash32>Murmur3f>Murmur3a(用于长字符串),以CityHash32>Murmur3a>Murmur3f(短字符串)。


3、CityHash64 与 CityHash128 的源程序

 

改编自:

Java版cityHash64 与cityHash128算法的实现icon-default.png?t=M85Bhttps://blog.csdn.net/aA518189/article/details/107867147参考了:

Clickhouse cityHash64 Java 实现icon-default.png?t=M85Bhttps://blog.csdn.net/lvxueshi/article/details/122505870

using System;

namespace Legalsoft.Truffer.Encryption
{
	/// <summary>
	/// Google CityHash 64,128位 算法
	/// https://blog.csdn.net/lvxueshi/article/details/122505870
	/// https://blog.csdn.net/aA518189/article/details/107867147
	/// </summary>
	public static class CityHash
	{
		private const long k0 = unchecked((long)0xc3a5c85c97cb3127L);
		private const long k1 = unchecked((long)0xb492b66fbe98f273L);
		private const long k2 = unchecked((long)0x9ae16a3b2f90404fL);
		private const long k3 = unchecked((long)0xc949d7c7509e6557L);

		/// <summary>
		/// 
		/// </summary>
		/// <param name="b"></param>
		/// <param name="i"></param>
		/// <returns></returns>
		private static long toLongLE(byte[] b, int i)
		{
			return (((long)b[i + 7] << 56) +
					((long)(b[i + 6] & 255) << 48) +
					((long)(b[i + 5] & 255) << 40) +
					((long)(b[i + 4] & 255) << 32) +
					((long)(b[i + 3] & 255) << 24) +
					((b[i + 2] & 255) << 16) +
					((b[i + 1] & 255) << 8) +
					((b[i + 0] & 255) << 0));
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="b"></param>
		/// <param name="i"></param>
		/// <returns></returns>
		private static long toIntLE(byte[] b, int i)
		{
			return (((b[i + 3] & 255L) << 24) +
					((b[i + 2] & 255L) << 16) +
					((b[i + 1] & 255L) << 8) +
					((b[i + 0] & 255L) << 0));
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="s"></param>
		/// <param name="pos"></param>
		/// <returns></returns>
		private static long fetch64(byte[] s, int pos)
		{
			return toLongLE(s, pos);
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="s"></param>
		/// <param name="pos"></param>
		/// <returns></returns>
		private static long fetch32(byte[] s, int pos)
		{
			return toIntLE(s, pos);
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="b"></param>
		/// <returns></returns>
		private static int staticCastToInt(byte b)
		{
			return b & 0xFF;
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="val"></param>
		/// <param name="shift"></param>
		/// <returns></returns>
		private static long rotate(long val, int shift)
		{
			// Avoid shifting by 64: doing so yields an undefined result.
			return shift == 0 ? val : ((long)((ulong)val >> shift)) | (val << (64 - shift));
		}

		/// <summary>
		/// On x86-64, and probably others, it's possible for 
		/// this to compileEquivalent to Rotate(), but requires the second arg to be non-zero.
		/// to a single instruction if both args are already in registers. 
		/// </summary>
		/// <param name="val"></param>
		/// <param name="shift"></param>
		/// <returns></returns>
		private static long rotateByAtLeast1(long val, int shift)
		{
			return ((long)((ulong)val >> shift)) | (val << (64 - shift));
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="val"></param>
		/// <returns></returns>
		private static long shiftMix(long val)
		{
			//return val ^ (val >>> 47);
			return val ^ ((long)((ulong)val >> 47));
		}

		/// <summary>
		/// 
		/// </summary>
		private const long kMul = unchecked((long)0x9ddfea08eb382d69L);

		/// <summary>
		/// 
		/// </summary>
		/// <param name="u"></param>
		/// <param name="v"></param>
		/// <returns></returns>
		private static long hash128to64(long u, long v)
		{
			long a = (u ^ v) * kMul;
			a ^= ((long)((ulong)a >> 47));
			//        long b = (u ^ a) * kMul;
			long b = (v ^ a) * kMul;
			b ^= ((long)((ulong)b >> 47));
			b *= kMul;
			return b;
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="u"></param>
		/// <param name="v"></param>
		/// <returns></returns>
		private static long hashLen16(long u, long v)
		{
			return hash128to64(u, v);
		}
		private static long hashLen16(long u, long v, long kmul)
		{
			long a = (u ^ v) * kmul;
			a ^= (a >> 47);
			long b = (v ^ a) * kmul;
			b ^= (b >> 47);
			b *= kmul;
			return b;
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="s"></param>
		/// <param name="pos"></param>
		/// <param name="len"></param>
		/// <returns></returns>
		private static long hashLen0to16(byte[] s, int pos, int len)
		{
			if (len >= 8)
			{
				/*
				long a = fetch64(s, pos);
				long b = fetch64(s, pos + len - 8);

				return hashLen16(a, rotateByAtLeast1(b + len, len)) ^ b;
				*/
				long kmul = k2 + len * 2;
				long a = fetch64(s, pos) + k2;
				long b = fetch64(s, pos + len - 8);
				long c = rotate(b, 37) * kmul + a;
				long d = (rotate(a, 25) + b) * kmul;
				return hashLen16(c, d, kmul);
			}

			if (len >= 4)
			{
				/*
				long a = fetch32(s, pos);
				return hashLen16(len + (a << 3), fetch32(s, pos + len - 4));
				*/
				long kmul = k2 + len * 2;
				long a = fetch32(s, pos + 0);
				return hashLen16((a << 3) + len, fetch32(s, pos + len - 4), kmul);
			}

			if (len > 0)
			{
				byte a = s[pos];
				byte b = s[pos + ((int)((uint)len >> 1))];
				byte c = s[pos + len - 1];
				int y = staticCastToInt(a) + (staticCastToInt(b) << 8);
				int z = len + (staticCastToInt(c) << 2);
				return shiftMix(y * k2 ^ z * k3) * k2;
			}

			return k2;
		}

		/// <summary>
		/// This probably works well for 16-byte strings as well, 
		/// but it may be overkill in that case.
		/// </summary>
		/// <param name="s"></param>
		/// <param name="pos"></param>
		/// <param name="len"></param>
		/// <returns></returns>
		private static long hashLen17to32(byte[] s, int pos, int len)
		{
			long a = fetch64(s, pos) * k1;
			long b = fetch64(s, pos + 8);
			long c = fetch64(s, pos + len - 8) * k2;
			long d = fetch64(s, pos + len - 16) * k0;
			return hashLen16(rotate(a - b, 43) + rotate(c, 30) + d, a + rotate(b ^ k3, 20) - c + len);

		}

		public static long reversalByte(long l)
		{
			/*
			ByteBuffer buffer = ByteBuffer.allocate(8);

			sbyte[] array = buffer.putLong(0, l).array();
			sbyte[] newArr = new sbyte[array.Length];
			for (int i = array.Length - 1; i >= 0; i--)
			{
				newArr[array.Length - i - 1] = array[i];
			}


			ByteBuffer buffer2 = ByteBuffer.wrap(newArr, 0, 8);

			//if(littleEndian){
				// ByteBuffer.order(ByteOrder) 方法指定字节序,即大小端模式(BIG_ENDIAN/LITTLE_ENDIAN)
				// ByteBuffer 默认为大端(BIG_ENDIAN)模式
				//buffer.order(ByteOrder.LITTLE_ENDIAN);
			//}

			buffer.order(ByteOrder.LITTLE_ENDIAN);
			return buffer.getLong();

			*/
			byte[] buf = BitConverter.GetBytes(l);
			byte[] newary = new byte[buf.Length];
			for (int i = buf.Length - 1; i >= 0; i--) newary[i] = buf[i];
			byte[] buf2 = (byte[])newary.Clone();
			return BitConverter.ToInt64(buf2, 0);
		}

		/*
		/// <summary>
		/// 
		/// </summary>
		/// <param name="s"></param>
		/// <param name="pos"></param>
		/// <param name="len"></param>
		/// <returns></returns>
		private static long hashLen33to64(byte[] s, int pos, int len)
		{
			long z = fetch64(s, pos + 24);
			long a = fetch64(s, pos) + (len + fetch64(s, pos + len - 16)) * k0;

			long b = rotate(a + z, 52);
			long c = rotate(a, 37);
			a += fetch64(s, pos + 8);
			c += rotate(a, 7);
			a += fetch64(s, pos + 16);
			long vf = a + z;
			long vs = b + rotate(a, 31) + c;
			a = fetch64(s, pos + 16) + fetch64(s, len - 32);
			z = fetch64(s, len - 8);
			b = rotate(a + z, 52);
			c = rotate(a, 37);
			a += fetch64(s, len - 24);
			c += rotate(a, 7);
			a += fetch64(s, len - 16);
			long wf = a + z;
			long ws = b + rotate(a, 31) + c;
			long r = shiftMix((vf + ws) * k2 + (wf + vs) * k0);
			return shiftMix(r * k0 + vs) * k2;
		}
		*/
		private static long hashLen33to64(byte[] s, int pos, int len)
		{
			long mul = k2 + len * 2;
			long a = fetch64(s, pos) * k2;

			long b = fetch64(s, pos + 8);
			long c = fetch64(s, pos + len - 24);
			long d = fetch64(s, pos + len - 32);
			long e = fetch64(s, pos + 16) * k2;
			long f = fetch64(s, pos + 24) * 9;
			long g = fetch64(s, pos + len - 8);
			long h = fetch64(s, pos + len - 16) * mul;
			long u = rotate(a + g, 43) + (rotate(b, 30) + c) * 9;
			long v = ((a + g) ^ d) + f + 1;
			long w = reversalByte((u + v) * mul) + h;
			long x = rotate(e + f, 42) + c;
			long y = (reversalByte((v + w) * mul) + g) * mul;
			long z = e + f + c;
			a = reversalByte((x + z) * mul + y) + b;
			b = shiftMix((z + a) * mul + d + h) * mul;
			return b + x;
		}


		/// <summary>
		/// 
		/// </summary>
		/// <param name="s"></param>
		/// <param name="pos"></param>
		/// <param name="len"></param>
		/// <returns></returns>
		public static long cityHash64(byte[] s, int pos, int len)
		{
			if (len <= 32)
			{
				if (len <= 16)
				{
					return hashLen0to16(s, pos, len);
				}
				else
				{
					return hashLen17to32(s, pos, len);
				}
			}
			else if (len <= 64)
			{
				return hashLen33to64(s, pos, len);
			}

			// For strings over 64 bytes we hash the end first, and then as we
			// loop we keep 56 bytes of state: v, w, x, y, and z.
			long x = fetch64(s, pos);
			long y = fetch64(s, pos + len - 16) ^ k1;
			long z = fetch64(s, pos + len - 56) ^ k0;
			long[] v = weakHashLen32WithSeeds(s, pos + len - 64, len, y);
			long[] w = weakHashLen32WithSeeds(s, pos + len - 32, len * k1, k0);
			z += shiftMix(v[1]) * k1;
			x = rotate(z + x, 39) * k1;
			y = rotate(y, 33) * k1;


			// Decrease len to the nearest multiple of 64, and operate on 64-byte chunks.
			len = (len - 1) & ~staticCastToInt((byte)63);
			do
			{
				x = rotate(x + y + v[0] + fetch64(s, pos + 16), 37) * k1;
				y = rotate(y + v[1] + fetch64(s, pos + 48), 42) * k1;
				x ^= w[1];
				y ^= v[0];
				z = rotate(z ^ w[0], 33);
				v = weakHashLen32WithSeeds(s, pos, v[1] * k1, x + w[0]);
				w = weakHashLen32WithSeeds(s, pos + 32, z + w[1], y);
				long tmp = x;
				x = z;
				z = tmp;
				pos += 64;
				len -= 64;
			} while (len != 0);


			return hashLen16(hashLen16(v[0], w[0]) + shiftMix(y) * k1 + z, hashLen16(v[1], w[1]) + x);
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="w"></param>
		/// <param name="x"></param>
		/// <param name="y"></param>
		/// <param name="z"></param>
		/// <param name="a"></param>
		/// <param name="b"></param>
		/// <returns></returns>
		private static long[] weakHashLen32WithSeeds(long w, long x, long y, long z, long a, long b)
		{

			a += w;
			b = rotate(b + a + z, 21);
			long c = a;
			a += x;
			a += y;
			b += rotate(a, 44);
			return new long[] { a + z, b + c };

		}

		/// <summary>
		/// Return a 16-byte hash for s[0] ... s[31], a, and b.
		/// Quick and dirty.
		/// </summary>
		/// <param name="s"></param>
		/// <param name="pos"></param>
		/// <param name="a"></param>
		/// <param name="b"></param>
		/// <returns></returns>
		private static long[] weakHashLen32WithSeeds(byte[] s, int pos, long a, long b)
		{
			return weakHashLen32WithSeeds(fetch64(s, pos + 0),
				fetch64(s, pos + 8),
				fetch64(s, pos + 16),
				fetch64(s, pos + 24),
				a, b);
		}

		private static long[] cityMurmur(byte[] s, int pos, int len, long seed0, long seed1)
		{

			long a = seed0;
			long b = seed1;
			long c = 0;
			long d = 0;

			int l = len - 16;
			if (l <= 0)
			{
				a = shiftMix(a * k1) * k1;
				c = b * k1 + hashLen0to16(s, pos, len);
				d = shiftMix(a + (len >= 8 ? fetch64(s, pos + 0) : c));
			}
			else
			{

				c = hashLen16(fetch64(s, pos + len - 8) + k1, a);
				d = hashLen16(b + len, c + fetch64(s, pos + len - 16));
				a += d;

				do
				{
					a ^= shiftMix(fetch64(s, pos + 0) * k1) * k1;
					a *= k1;
					b ^= a;
					c ^= shiftMix(fetch64(s, pos + 8) * k1) * k1;
					c *= k1;
					d ^= c;
					pos += 16;
					l -= 16;
				} while (l > 0);
			}

			a = hashLen16(a, c);
			b = hashLen16(d, b);

			return new long[] { a ^ b, hashLen16(b, a) };
		}

		private static long[] cityHash128WithSeed(byte[] s, int pos, int len, long seed0, long seed1)
		{
			if (len < 128)
			{
				return cityMurmur(s, pos, len, seed0, seed1);
			}

			long[] v = new long[2], w = new long[2];
			long x = seed0;
			long y = seed1;
			long z = k1 * len;
			v[0] = rotate(y ^ k1, 49) * k1 + fetch64(s, pos);
			v[1] = rotate(v[0], 42) * k1 + fetch64(s, pos + 8);
			w[0] = rotate(y + z, 35) * k1 + x;
			w[1] = rotate(x + fetch64(s, pos + 88), 53) * k1;

			// This is the same inner loop as CityHash64(), manually unrolled.
			do
			{
				x = rotate(x + y + v[0] + fetch64(s, pos + 16), 37) * k1;
				y = rotate(y + v[1] + fetch64(s, pos + 48), 42) * k1;

				x ^= w[1];
				y ^= v[0];

				z = rotate(z ^ w[0], 33);
				v = weakHashLen32WithSeeds(s, pos, v[1] * k1, x + w[0]);
				w = weakHashLen32WithSeeds(s, pos + 32, z + w[1], y);

				{
					long swap = z;
					z = x;
					x = swap;
				}
				pos += 64;
				x = rotate(x + y + v[0] + fetch64(s, pos + 16), 37) * k1;
				y = rotate(y + v[1] + fetch64(s, pos + 48), 42) * k1;
				x ^= w[1];
				y ^= v[0];
				z = rotate(z ^ w[0], 33);
				v = weakHashLen32WithSeeds(s, pos, v[1] * k1, x + w[0]);
				w = weakHashLen32WithSeeds(s, pos + 32, z + w[1], y);
				{
					long swap = z;
					z = x;
					x = swap;
				}
				pos += 64;
				len -= 128;
			} while (len >= 128);

			y += rotate(w[0], 37) * k0 + z;
			x += rotate(v[0] + z, 49) * k0;

			// If 0 < len < 128, hash up to 4 chunks of 32 bytes each from the end of s.
			for (int tail_done = 0; tail_done < len;)
			{
				tail_done += 32;
				y = rotate(y - x, 42) * k0 + v[1];
				w[0] += fetch64(s, pos + len - tail_done + 16);
				x = rotate(x, 49) * k0 + w[0];
				w[0] += v[0];
				v = weakHashLen32WithSeeds(s, pos + len - tail_done, v[0], v[1]);
			}

			// At this point our 48 bytes of state should contain more than
			// enough information for a strong 128-bit hash.  We use two
			// different 48-byte-to-8-byte hashes to get a 16-byte final result.

			x = hashLen16(x, v[0]);
			y = hashLen16(y, w[0]);

			return new long[] { hashLen16(x + v[1], w[1]) + y, hashLen16(x + w[1], y + v[1]) };
		}

		internal static long[] cityHash128(byte[] s, int pos, int len)
		{

			if (len >= 16)
			{
				return cityHash128WithSeed(s, pos + 16, len - 16, fetch64(s, pos) ^ k3, fetch64(s, pos + 8));
			}
			else if (len >= 8)
			{
				return cityHash128WithSeed(new byte[0], 0, 0, fetch64(s, pos) ^ (len * k0), fetch64(s, pos + len - 8) ^ k1);
			}
			else
			{
				return cityHash128WithSeed(s, pos, len, k0, k1);
			}
		}

	}
}

4、调用方法的演示代码

private void button1_Click(object sender, EventArgs e)
{
    string str = "马列主义";
    byte[] buf = Encoding.Default.GetBytes(str);
    long hash64 = CityHash.cityHash64(buf, 0, buf.Length);
    long[] hash128 = CityHash.cityHash128(buf, 0, buf.Length);
    label16.Text = hash64 + " " + hash128[0] + "." + hash128[1];
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/117313.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

“刀片嗓”“水泥鼻”“咳出肺”可以这样缓解!

很多人感染新冠后&#xff0c;咽痛、鼻塞、干咳和其他不适&#xff0c;非常不舒服&#xff0c;在网上讨论也总结了“刀片嗓”、“水泥鼻”、“咳出肺”三个字生动地展现了他们的不适。今天&#xff0c;对于这三种症状&#xff0c;今天就为大家带来一些缓解的小方法。 病症一&am…

机器学习中的评价指标

1.MSE&#xff08;mean squared error&#xff09; 叫做均方误差&#xff0c;又称L2损失。取平方有一个特性&#xff0c;它惩罚更大的错误更多&#xff08;毕竟都取平方了&#xff09;。方差一般用来计算样本的离散程度&#xff0c;而均方误差则可以用做衡量模型拟合的一个度量…

Linux串口编程详解(阻塞模式、非阻塞模式、select函数)

前言&#xff1a;之前一直觉得串口编程很简单&#xff0c;这两天仔细研究后发现串口里的各种参数还挺复杂&#xff0c;稍不注意就容易出错&#xff0c;这里总结一下网上的各种文章及自己的理解与实践。 open 函数 功能描述&#xff1a;用于打开或创建文件&#xff0c;成功则返…

【05】概率图表示之马尔可夫随机场

概率图表示之马尔可夫随机场 文章目录马尔可夫随机场正式定义与贝叶斯网络的比较马尔可夫随机场中的独立性条件随机场示例正式定义示例&#xff08;续&#xff09;CRF特性因子图贝叶斯网络可以以一种紧凑的方式表示许多概率分布。然而&#xff0c;我们在前一章中已经看到&…

笔试强训(8)

笔试题1:密码强度等级密码强度等级_牛客题霸_牛客网 在这个题中: 1)统计密码的长度直接通过length()来进行解决 2)统计大写字母和小写字母的个数分别在函数里面定义两个变量来进行解决 3)统计数字和富豪也是分别用两个变量来进行保存 import java.util.Scanner;// 注意类名必须…

记一次 Maven 打包后,第三方无法使用的排查记录

你好&#xff0c;我是悟空。 本文主要内容如下&#xff1a; 前言 最近遇到一个需求&#xff1a; 写一个工具类的 JAR 包&#xff0c;然后提供给第三方使用。 期间遇到了一些问题&#xff1a; 第三方引入 JAR 包后&#xff0c;无法 import。第三方引入 JAR 包后&#xff0c…

你可以不看世界杯,但你一定要知道这些

2022卡塔尔世界杯&#xff0c;阿根廷夺冠&#xff0c;举世沸腾。 ​夺冠之路&#xff0c;遍布荆棘 时隔36年&#xff0c;阿根廷再次夺得大力神杯&#xff0c;回望夺冠之路&#xff0c;坎坷遍布&#xff0c;荆棘丛生。 2006年夏天&#xff0c;梅西第一次参加世界杯。时任阿根廷…

Mybatis源码(一)获取数据源

前言 Mybatis做为一种半ORM框架&#xff08;半&#xff1a;需要手动写sql&#xff09;。ORM&#xff08;Object Relational Mapping&#xff09;的技术本质是&#xff1a;ORM框架将对象的值 映射到 对应数据库类型&#xff1a; 如 String -> varchar。 且mybatis分为两种实…

数字孪生核电站促进界面监测的应用实践

未来核电站将向着数字化、智能化发展,“少人值守、智能监测”会广泛应用于核电站运行管理。利用数字孪生技术,可以对实体核电站和孪生核电站的数据进行交换分析,促进核电站的运行管理和监测,更好地确保反应堆运行安全。 数字孪生核电站促进界面监测的应用实践 北京智汇云舟科技…

h5中使用微信分享

1.需要 绑定域名&#xff1a; 先登录微信公众平台进入“公众号设置”的“功能设置”里填写“JS接口安全域名”&#xff08;即访问前端项目对应的域名)。 2.在项目中引入sdk: 在需要调用 JS 接口的页面引入如下 JS 文件&#xff0c;&#xff08;支持https&#xff09;&#xff…

搭vue项目(初级版)

这个项目只有 会员管理和直播管理两个模块。创建两个模块是为了验证一下路由跳转。 下载项目&#xff1a; 可以到我的资源中下载压缩包 或者 git clone 前端项目搭建: 前端搭建的项目&#xff0c;仅供学习使用 1.安装vue-cli,全局只需要安装一次&#xff0c;如果安装过一次&am…

MyBatisPlus ---- 入门案例

MyBatisPlus ---- 入门案例1. 开发环境2. 创建数据库及表a>创建表b>添加数据3. 创建SpringBoot工程a>初始化工程b>引入依赖c>idea中安装lombok插件4. 编写代码a>配置application.ymlb>启动类c>添加实体d>添加mappere>测试f>添加日志1. 开发环…

了解 Oracle 中单引号与双引号的用法,一篇文章教会你!

无论测试或者开发&#xff0c;对数据库的增删改查都是家常便饭。但有些小知识是经常被忽略&#xff0c;却又不能不去了解的&#xff0c;例如单引号和双引号的用法和区别&#xff0c;看完这一篇&#xff0c;你肯定会有收获。 首先我们要区别一个概念&#xff0c;即单引号(‘)和双…

docker应用部署示例

Docker 应用部署 一、部署MySQL 搜索mysql镜像 docker search mysql拉取mysql镜像 docker pull mysql:5.6创建容器&#xff0c;设置端口映射、目录映射 # 在/root目录下创建mysql目录用于存储mysql数据信息 mkdir ~/mysql cd ~/mysqldocker run -id \ -p 3307:3306 \ --na…

如何通过文档管理控制合同管理

如何通过文档管理控制合同管理 如果您的公司处理的合同比以往任何时候都多&#xff0c;那么您并不孤单。这种指数级增长的原因包括日益增长的监管要求、供应链问题以及全球化带来的业务关系的复杂性。此外&#xff0c;员工更频繁地换工作&#xff0c;因此&#xff0c;需要管理更…

Unity实用小工具—以对象形式操作Sqlite

一、介绍 1.1、版本说明&#xff1a;使用的Unity版本为个人版2020.3.39&#xff0c;数据库为Sqlite&#xff08;一个轻量级跨平台数据库&#xff09;&#xff0c;Sqlite的查看管理工具可以在网上下载https://dbeaver.io/download/&#xff0c;可以直接保存下来使用。 1.2、数…

微服务(四)——统一网关

目录1. 概念2. 实现网关1. 实现流程2. 小结3. 断言工厂4. 过滤器工厂1. GatewayFilter2. GlobalFilter3. 过滤器的执行顺序5. 解决跨域问题1. 概念 网关的作用&#xff1a; 认证、鉴权服务路由、负载均衡请求限流 网关的实现&#xff1a; gateway 基于Spring5中提供的WebFlu…

linux 设置登录提示语

勿以恶小而为之&#xff0c;勿以善小而不为---- 刘备 /etc/motd 文件里面 保存的是 登录后提示语 vim /etc/motd可以放置自定义的 文字信息 -------------------- 每天都要加油努力噢&#xff0c;岳泽霖!!! -------------------登录之后&#xff0c;就会展示信息: 参考链接: …

【Linux】Linux命令行git的使用

前进才是唯一的方向 文章目录一、git是什么&#xff1f;二、gitee仓库创建1.新建仓库2.复制仓库链接3.克隆远端仓库到本地来三、git提交代码1.下载git2. 配置用户名和邮箱&#xff08;否则git commit无法正常使用&#xff09;3. git提交代码三板斧3.1 git add&#xff08;将代…

git merge合并开发分支到上线分支遇到的问题,提示 no new changes

git merge 后 push 到 Gerrit 失败&#xff0c;提示 no new changes 解决思路&#xff1a; 分析&#xff1a;no new changes 的意思&#xff0c;是说&#xff0c;这个合并&#xff0c;是个线性的合并。而合并的那些历史的 commit 节点&#xff0c;在 gerrit 上都已经评审过了&…