短連結生成

hatch發表於2018-04-24

要求:

1.隨機
2.8位字串
3.不重複
4.不佔儲存
5.效率
7.62進位制
複製程式碼
package com.nd.disk.lib.util;

import java.util.HashSet;

public class ShortUrlUtil {

	private static char[] charSet = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz".toCharArray();

	private static final long MIN = 3521614606208L;

	private static final long SUFFIX_ID = ((1L << 46) - 1);

	private static final long PRE_ID = (3L << 46);

	private static final long MAX_ID = 211106232532991L;

	public static String next(long id) {

		if (id < 0 || id > MAX_ID) {
			throw new IllegalArgumentException("Illegal id: " + id);
		}

		//非線性
		id = swap(id, 7, 0);
		id = swap(id, 6, 1);
		
		// Id後46位
		long value = id & SUFFIX_ID;
		
		// Id後46位的最低八位和高1-9位交換
		value = (((value >> 8) | ((value & 255) << 38)));
		
		// Id前兩位
		id = (id & PRE_ID) | value;

		id += MIN;
		
		String str = convertDecimalToBase62(id);
		
		return str;
	}

	/**
	 * xxxx xxxx xxxx x0xx xxxx xx0x xxxx xxxx|0000 0000 0000 0b00 0000 00a0 0000 0000
	 */
	private static long swap(long value, int x, int y) {

		return (value & (~(1 << x)) & (~(1 << y))) | (((value >> x) & 1) << y) | (((value >> y) & 1) << x);
	}

	private static String convertDecimalToBase62(long number) {
		Long rest = number;
		StringBuilder result = new StringBuilder(0);
		while (rest != 0) {

			char aa = charSet[(int) (rest - (rest / 62) * 62)];
			result.append(aa);
			rest = rest / 62;
		}

		return result.reverse().toString();

	}

	private ShortUrlUtil() {
	};

	public static void main(String[] args) throws Exception {

		HashSet<String> values = new HashSet<>();

		long index = 0;
		for (long id = 0L; ; id++) {
			String value = ShortUrlUtil.next(id);

			if (values.contains(value)) {
				throw new RuntimeException("same...,count:" + values.size() + "; value: " + value);
			}
			values.add(value);

			System.out.println(value);

			index++;

			if (index == 50000000) {
				index = 0;
				values.clear();
				System.out.println(id);
			}
		}
	}
}

複製程式碼

相關文章