String 转化的问题 我想把这个a71e2023-9aaa-4d4e-a83d-4c71f6c41911字符串转为16个字符或更少的字符串,要是唯一的,请问怎么实现? 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 答:很简单啊。每四位一组,构成一个UNICODE字符。String ss=""+(char)Integer.parseInt("a71e",16)+(char)Integer.parseInt("2023",16)+ (char)Integer.parseInt("9aaa",16)+....由于-位置固定,因此可以不考虑。这样只要8个字符的字符串就行了。而且还可以正确还原出来。 好象不行哦String ss2=""+(char)Integer.parseInt("2023",16);System.out.println("String="+ss2);输出结果:String=? 1.先生成你开始的32位不重复的字符串。 UUID uuid = UUID.randomUUID(); return uuid.toString();2.从右边截取16位。我这里用到Apache的Commons-lang包。下载这个包,或者你手写截取也可。 StringUtils.right(MiscToolBox.getSimpleId(), 16);3.通过上面生成的16位ID,其实重复的几率已经很低了。但是为防止万一,需要先从数据库中查一下。没有插入,否则再生成一遍这个ID。 String id = ""; while(true) { id = 上面生成ID的方面; if (通过Id查找数据库中这个ID的数量>0) //再生成一遍 continue; else break; } return id ; 楼上的,我的32位UUID不是我自己生成的,是别人传过来的,我不可能再重新生成一遍,截取后16位我自己也想过,但是确实有可能出现重复的 16个?MD5Hash下说 /** * MD5加密算法,进行了简单的封装,以适用于加,解密字符串的校验。 * * @param buf 需要MD5加密字节数组。 * @param offset 加密数据起始位置。 * @param length 需要加密的数组长度。 * @return */ public static byte[] MD5Hash(byte[] buf, int offset, int length) throws Exception { MessageDigest md = MessageDigest.getInstance("MD5"); md.update(buf, offset, length); return md.digest(); } /** * 字节数组转换为二行制表示 * * @param inStr 需要转换字节数组。 * @return 字节数组的二进制表示 */ public static String byte2hex(byte[] inStr) { String stmp; StringBuffer out = new StringBuffer(inStr.length * 2); for (int n = 0; n < inStr.length; n++) { // 字节做“与”运算,去除高位置字节 11111111 stmp = Integer.toHexString(inStr[n] & 0xFF); if (stmp.length() == 1) { // 如果是0至F的单位字符串,则添加0 out.append("0" + stmp); } else { out.append(stmp); } } return out.toString(); } String c = "a71e2023-9aaa-4d4e-a83d-4c71f6c41911"; try { String h = Md5.byte2hex(Md5.MD5Hash(c.getBytes(), 0, c.length())); System.out.println(h); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); }得到的结果:eabf857ef96f7a2f93545c718e4e449a是32位的啊 楼主数据库字段是 char(16) 类型的? 给楼主个思路:"a71e2023-9aaa-4d4e-a83d-4c71f6c41911" 如果把其中-去掉,可以把剩下的字符看作一个32位的16进制整数,按每位16进制对应于4位二进制信息,UUID可以看作一个 32 * 4 = 128 bit 的数据块(本质上也如此),而数据库中 char(16) 字段的编码如果是Unicode的而每个Unicode字符需要16位即2个字节表示,那么16个字节共 16 * 16 = 256 bit,实际上不是数据量的压缩而是扩充,所以如果能修改数据库结构,可以直接存储这个128位的数据块,带来的好处是即节省数据库空间,又可以在二进制基础上直接作比较运算,效率要比字符串比较高(省去了编码解码的运算和时间)。 /* * FileName: Test.java * Author: SageZk * Date: 2008-06-03 */public class Test { public static void main(String[] args) { String uuid = "a71e2023-9aaa-4d4e-a83d-4c71f6c41911"; String st = uuid.replaceAll("\\-", ""); StringBuffer sb = new StringBuffer(16); for (int i = 0; i < 32; i = i + 2) { sb.append((char) (Integer.parseInt(st.substring(i, i + 2), 16) + '我')); } String sr = sb.toString(); System.out.println(uuid); System.out.println(sr); }}可以把 '我' 换成其他字符。 楼上的输出结果:"抸戯戱戴披抻扞扟抹扎扝抂指拕截戢"数据库里char(16)能存下16个中文字符吗? String uuid = "a71e2023-9aaa-4d4e-a83d-4c71f6c41911"; String st = uuid.replaceAll("\\-", ""); StringBuffer sb = new StringBuffer(16); for (int i = 0; i < 32; i = i + 2) { sb.append((char) (Integer.parseInt(st.substring(i, i + 2), 16) + 'a')); } String sr = sb.toString(); System.out.println(uuid); System.out.println(sr); System.out.println("?????????????zr".equals(sr));输出结果:a71e2023-9aaa-4d4e-a83d-4c71f6c41911?????????????zrfalse这样我从数据库取出来不是不能匹配了吗 那要看 char(16) 字段编码类型,如果是 Unicode 或 GBK 的都没问题。 测试成功,感谢sagezk的帮助,结分 可以用256进制来表示你那个字符串,就从32位缩到16位了(11111111(2)=FF(16)=ÿ(256))不过有个缺点,字符串传递的时候不能复制+粘贴,那样的话有些字符就失效了,AscII中有很多不可打印字符不过数据始终用二进制传递就可以了,,应该不困难public class Java2 { public static String getConvString(String str) { String tmp=str.replace("-",""); String strOut=""; for (int i=0; i<tmp.length()-1; i+=2) { try { strOut+=(char)Integer.parseInt(tmp.substring(i,i+2),16); } catch (Exception e) {return null;} } return strOut; } public static String getSourceString(String str) { String strOut=""; for (int i=0; i<str.length(); i++) { if (i==4 || i==6 || i==8 || i==10) { strOut+="-"; } int n=(int)(str.charAt(i)); strOut+=Integer.toHexString(n); } return strOut; } public static void main(String[] args) { String s="a71e2023-9aaa-4d4e-a83d-4c71f6c41911"; String string=getConvString(s); System.out.println("原来 的字符串: "+s); System.out.println("转换过的字符串: "+string); System.out.println("还原过的字符串: "+getSourceString(string)); }}得到的结果:原来 的字符串: a71e2023-9aaa-4d4e-a83d-4c71f6c41911转换过的字符串: § #??MN¨=Lq??还原过的字符串: a71e2023-9aaa-4d4e-a83d-4c71f6c41911 java IO文件操作入门经典例子-学会这些例子,你会发现IO是如此简单 AOP到底是什么,能举例说明一下吗? 急,第一次做小项目,在结尾的时候遇到如此问题。。。。。 帮帮忙,这是怎么回事? 如何禁止JTable的复制粘贴 你是对日软件开发者吗? 一个简单问题 怎样将String数组包存成.txt文件? 命令行中执行jar文件时怎么样才能找到依赖的jar包! 明天回家过年,散掉全部的30分,大家别笑话少啊,再把所有的帖子揭掉!!! jbuilder DataOutputStream -> writeUTF 方法
String ss=""+(char)Integer.parseInt("a71e",16)+(char)Integer.parseInt("2023",16)+
(char)Integer.parseInt("9aaa",16)+....
由于-位置固定,因此可以不考虑。
这样只要8个字符的字符串就行了。
而且还可以正确还原出来。
String ss2=""+(char)Integer.parseInt("2023",16);
System.out.println("String="+ss2);
输出结果:
String=?
return uuid.toString();
2.从右边截取16位。我这里用到Apache的Commons-lang包。下载这个包,或者你手写截取也可。 StringUtils.right(MiscToolBox.getSimpleId(), 16);
3.通过上面生成的16位ID,其实重复的几率已经很低了。但是为防止万一,需要先从数据库中查一下。没有插入,
否则再生成一遍这个ID。 String id = "";
while(true) {
id = 上面生成ID的方面;
if (通过Id查找数据库中这个ID的数量>0) //再生成一遍
continue;
else break;
}
return id ;
MD5Hash下说 /**
* MD5加密算法,进行了简单的封装,以适用于加,解密字符串的校验。
*
* @param buf 需要MD5加密字节数组。
* @param offset 加密数据起始位置。
* @param length 需要加密的数组长度。
* @return
*/
public static byte[] MD5Hash(byte[] buf, int offset, int length)
throws Exception {
MessageDigest md = MessageDigest.getInstance("MD5");
md.update(buf, offset, length);
return md.digest();
} /**
* 字节数组转换为二行制表示
*
* @param inStr 需要转换字节数组。
* @return 字节数组的二进制表示
*/
public static String byte2hex(byte[] inStr) {
String stmp;
StringBuffer out = new StringBuffer(inStr.length * 2); for (int n = 0; n < inStr.length; n++) {
// 字节做“与”运算,去除高位置字节 11111111
stmp = Integer.toHexString(inStr[n] & 0xFF);
if (stmp.length() == 1) {
// 如果是0至F的单位字符串,则添加0
out.append("0" + stmp);
} else {
out.append(stmp);
}
}
return out.toString();
}
try {
String h = Md5.byte2hex(Md5.MD5Hash(c.getBytes(), 0, c.length()));
System.out.println(h);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}得到的结果:eabf857ef96f7a2f93545c718e4e449a
是32位的啊
* FileName: Test.java
* Author: SageZk
* Date: 2008-06-03
*/public class Test { public static void main(String[] args) {
String uuid = "a71e2023-9aaa-4d4e-a83d-4c71f6c41911";
String st = uuid.replaceAll("\\-", "");
StringBuffer sb = new StringBuffer(16);
for (int i = 0; i < 32; i = i + 2) {
sb.append((char) (Integer.parseInt(st.substring(i, i + 2), 16) + '我'));
}
String sr = sb.toString();
System.out.println(uuid);
System.out.println(sr); }}
可以把 '我' 换成其他字符。
数据库里char(16)能存下16个中文字符吗?
String uuid = "a71e2023-9aaa-4d4e-a83d-4c71f6c41911";
String st = uuid.replaceAll("\\-", "");
StringBuffer sb = new StringBuffer(16);
for (int i = 0; i < 32; i = i + 2) {
sb.append((char) (Integer.parseInt(st.substring(i, i + 2), 16) + 'a'));
}
String sr = sb.toString();
System.out.println(uuid);
System.out.println(sr);
System.out.println("?????????????zr".equals(sr));输出结果:
a71e2023-9aaa-4d4e-a83d-4c71f6c41911
?????????????zr
false
这样我从数据库取出来不是不能匹配了吗
(11111111(2)=FF(16)=ÿ(256))不过有个缺点,字符串传递的时候不能复制+粘贴,那样的话有些字符就失效了,AscII中有很多不可打印字符
不过数据始终用二进制传递就可以了,,应该不困难
public class Java2 {
public static String getConvString(String str) {
String tmp=str.replace("-","");
String strOut="";
for (int i=0; i<tmp.length()-1; i+=2) {
try {
strOut+=(char)Integer.parseInt(tmp.substring(i,i+2),16);
} catch (Exception e) {return null;}
}
return strOut;
}
public static String getSourceString(String str) {
String strOut="";
for (int i=0; i<str.length(); i++) {
if (i==4 || i==6 || i==8 || i==10) {
strOut+="-";
}
int n=(int)(str.charAt(i));
strOut+=Integer.toHexString(n);
}
return strOut;
}
public static void main(String[] args) {
String s="a71e2023-9aaa-4d4e-a83d-4c71f6c41911";
String string=getConvString(s);
System.out.println("原来 的字符串: "+s);
System.out.println("转换过的字符串: "+string);
System.out.println("还原过的字符串: "+getSourceString(string));
}
}
得到的结果:原来 的字符串: a71e2023-9aaa-4d4e-a83d-4c71f6c41911
转换过的字符串: § #??MN¨=Lq??
还原过的字符串: a71e2023-9aaa-4d4e-a83d-4c71f6c41911