Arc-03-26-相册图片短码编码实现

应用中需要上传用户图片,不想数据库单独维护图片的信息,想直接从编码定位到图片文件,又不想编码太长,所以需要压缩数字串。

 

 

/**
 * 64进制和10进制的转换类
 * 
 * @author 
 * 
 */
public class compressEncodeing {
	final static String PHOTOS_PREFIX = "H";
	final static String DEFUALT_IMAGE_SUBFIX = ".jpg";
	final static String PLACEHOLDER = "-";
	final static String UNDERLINE = "_";
	final static String SEPARATOR = "/";
	final static String DOT = ".";
	final static String[] IMAGES_TYPE = { "bmp", "gif", "jpg", "png" };
	final static char[] digits = { '0', '1', '2', '3', '4', '5', '6', '7', '8',
			'9', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l',
			'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y',
			'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L',
			'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y',
			'Z', '+', '/', };

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		String url = getEncodePhotoUrl(1234567890, "png");
		System.out.println(url);

		url = getDecodePhotoName(url + "_640x480.png");

		System.out.println(url);

	}

	/**
	 * 根据 userID 返回图片的 URL 编码 编码规则,共四段组成
	 * 编码前:H(1位长相册类型)-1234567890(10位长用户ID)-1325137433192(13位毫秒)-2(1位随机码)-3
	 * (图片类型码) 编码后:H(1位长相册相册)19Bwbi(6位长用户ID)ji8m99E(7位毫秒)-n(1位随机码)
	 * 例:H19Bwbiji8m99E-n
	 * 
	 * @param userID
	 * @param shift
	 * @return encoded url
	 */
	public static String getEncodePhotoUrl(long userID, String suffix) {
		int suffixCode = -1;
		for (int i = 0; i < IMAGES_TYPE.length; i++) {
			if (IMAGES_TYPE[i].indexOf(suffix) != -1) {
				suffixCode = i;
				break;
			}
		}
		return PHOTOS_PREFIX
				+ prefixFormat(CompressNumber(userID, 6), 6)
				+ prefixFormat(CompressNumber(System.currentTimeMillis(), 6), 7)
				+ (CompressNumber((int) (Math.random() * 10), 6))
				+ (suffixCode == -1 ? 0 : suffixCode);
	}

	/**
	 * 根据编码后的图片的 URL 返回真实的图片文件名 编码规则
	 * 解码前:H(1位长相册相册)19Bwbi(6位长用户ID)ji8m99E(7位毫秒)-n(2位随机码)_640x480(size).png(后缀)
	 * 解码后:H(1位长相册类型)/1234567890(10位长用户ID)/1325137433192(13位毫秒)23(2位随机码)
	 * 例:H19Bwbiji8m99E-n_640x480.png ->
	 * /H/1234567890/132513743319223_640x480.png
	 * 
	 * @param url
	 * @return decoded photo file name
	 */
	public static String getDecodePhotoName(String url) {
		// 必须是大于 16位
		if (url == null || url.length() < 16)
			return null;
		String encodedUrl = url.substring(0, url.indexOf(UNDERLINE));
		// 有效编码必须是 16 位
		if (encodedUrl == null || encodedUrl.length() != 16)
			return null;

		String size = url.substring(url.indexOf(UNDERLINE), url.indexOf(DOT));
		String suffix = url.substring(url.indexOf(DOT), url.length());

		return encodedUrl.substring(0, 1) + SEPARATOR
				+ UnCompressNumber(encodedUrl.substring(1, 7)) + SEPARATOR
				+ UnCompressNumber(encodedUrl.substring(7, 14))
				+ UnCompressNumber(encodedUrl.substring(14, 15)) + size
				+ suffix;

	}

	/**
	 * 把10进制的数字转换成64进制
	 * 
	 * @param number
	 * @param shift
	 * @return
	 */
	private static String CompressNumber(long number, int shift) {
		char[] buf = new char[64];
		int charPos = 64;
		int radix = 1 << shift;
		long mask = radix - 1;
		do {
			buf[--charPos] = digits[(int) (number & mask)];
			number >>>= shift;
		} while (number != 0);
		return new String(buf, charPos, (64 - charPos));
	}

	/**
	 * 把64进制的字符串转换成10进制
	 * 
	 * @param decompStr
	 * @return
	 */
	private static long UnCompressNumber(String decompStr) {
		long result = 0;
		for (int i = decompStr.length() - 1; i >= 0; i--) {
			if (i == decompStr.length() - 1) {
				result += getCharIndexNum(decompStr.charAt(i));
				continue;
			}
			for (int j = 0; j < digits.length; j++) {
				if (decompStr.charAt(i) == digits[j]) {
					result += ((long) j) << 6 * (decompStr.length() - 1 - i);
				}
			}
		}
		return result;
	}

	/**
	 * 
	 * @param ch
	 * @return
	 */
	private static long getCharIndexNum(char ch) {
		int num = ((int) ch);
		if (num >= 48 && num <= 57) {
			return num - 48;
		} else if (num >= 97 && num <= 122) {
			return num - 87;
		} else if (num >= 65 && num <= 90) {
			return num - 29;
		} else if (num == 43) {
			return 62;
		} else if (num == 47) {
			return 63;
		}
		return 0;
	}

	/**
	 * 格式化文本,按固定长度,位数不够在前面补“-”
	 * 
	 * @param soucre
	 *            原来的文本
	 * @param length
	 *            固定长度值
	 * @return String 格式化后文本
	 */
	public static String prefixFormat(String soucre, int length) {
		//
		return String.format("%" + length + "s", soucre).replaceAll(" ",
				PLACEHOLDER);
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值