Java 双向字符串哈希函数
我想得到字符串的唯一数字表示形式。我知道有很多方法可以做到这一点,我的问题是你认为哪种方法最好?我不想有负数-所以java中的hashcode()函数不是很好,尽管我可以重写它。。。但我宁愿不要,因为我不是那么自信,也不想意外地弄坏东西 我的字符串都是语义web URI。使用数字表示的原因是,当我在页面上显示URI的数据时,我需要将某些内容传递到查询字符串中,或者放入javascript中的各个字段中。URI本身太笨重,当您将URI作为URI中的值时,它看起来很糟糕 基本上,我希望有一个名为Java 双向字符串哈希函数,java,string,hashcode,Java,String,Hashcode,我想得到字符串的唯一数字表示形式。我知道有很多方法可以做到这一点,我的问题是你认为哪种方法最好?我不想有负数-所以java中的hashcode()函数不是很好,尽管我可以重写它。。。但我宁愿不要,因为我不是那么自信,也不想意外地弄坏东西 我的字符串都是语义web URI。使用数字表示的原因是,当我在页面上显示URI的数据时,我需要将某些内容传递到查询字符串中,或者放入javascript中的各个字段中。URI本身太笨重,当您将URI作为URI中的值时,它看起来很糟糕 基本上,我希望有一个名为Re
Resource
的类,它将如下所示
Resource{
int id;
String uri;
String value; // this is the label or human readable name
// .... other code/getters/setters here
public int getId(){
return id = stringToIntFunction();
}
private int stringToIntFunction(String uri){
// do magic here
}
}
您是否可以建议一个函数在以下情况下执行此操作:
还有其他我没有考虑的重要问题吗?如果你想要它是可逆的,你就有麻烦了。散列被设计为单向的 特别是,考虑到
int
有32位信息,而char
有16位信息,要求可逆性意味着您只能拥有零、一个或两个字符的字符串(即使是假设您乐意将“”编码为“\0\0”或类似的内容)。当然,这是假设你没有任何存储空间。如果您可以使用存储,那么只需按顺序存储数字。。。比如:
private int stringToIntFunction(String uri) {
Integer existingId = storage.get(uri);
if (existingId != null) {
return existingId.intValue();
}
return storage.put(uri);
}
这里storage.put()
将在内部增加一个计数器,将URI存储为与该计数器值关联,然后返回它。我猜那不是你想要的
基本上,要执行可逆加密,我会先使用标准加密库将字符串转换为二进制格式(例如,使用UTF-8)。我希望结果是一个字节[]
如果不一定是可逆的,我会考虑只使用正常<代码> HASCODE()/<代码>结果的绝对值(但是映射<代码>整数.MINVALION<代码>,因为它的绝对值不能被表示为<代码> int <代码> > .< /P> < P>散列是单向的。(这也是它们有固定长度而不考虑输入大小的部分原因)。如果您需要双向编码,您可以使用Base64编码
为什么不能有负数?URI从哪里来?它们在数据库中吗?为什么不使用数据库键ID?如果它们不在数据库中,您可以为给定一组变量/参数的用户生成它们吗?(因此查询字符串只包含foo=1&bar=2之类的内容,您可以在服务器或JavaScript端生成URL)“唯一表示法”意味着Java提供的string.hashcode将是无用的-您很快就会遇到两个URI共享相同的hashcode 任何双向方案都将导致难以处理的字符串,除非将URI存储在数据库中并使用记录ID作为唯一标识符就单向性而言,MD5哈希比简单的哈希代码更独特(但决不是唯一的),但根据您的定义,可能会接近“笨拙”!鉴于上述所有剩余操作(哈希函数是单向的),我会选择两种可能的解决方案:
- 使用一些加密函数来获取表示URL的长字符串(您将获得类似->param=456ab894ce897b98f的内容(根据URL的不同,可以更长和/或更短)。例如,请参阅DES加密
- 跟踪数据库中的URL(也可以是一个简单的基于文件的数据库,如SQLite),这样就可以有效地获得uint URL等价性
rossum谢谢Jon,我可能不得不同意你的第二个建议。但是我不确定你所说的“将Integer.MIN_值映射到某个特定的值是什么意思,因为它的绝对值不能表示为int”,不要担心回答这个问题,对于单向情况,有很多材料(等等)@Ankur:Integer.MIN_值的绝对值是2147483648。但是,一个整数可以表示的最大正数是2147483647。因此,你必须确保不要对Integer.MIN_值调用Math.abs,而是以不同的方式处理它。是的,理想情况下,我不想查找ID的全局存储。使用加密算法似乎有意义。@安克尔:但你最初的问题是URI太大了,对吧?加密对这没什么帮助。为了保存一个很长的解释(在一个很小的盒子里),我会说我一直在使用db密钥ID,但这会降低我应用程序不同部分的性能。@Ankur有没有机会通过缓存解决这个问题?基本上是Jon建议的,一个全局哈希表。是的。我想的是,1)计算一些哈希值,2)按数字顺序存储3)定期查看此表,然后添加a,B,等等,到第二、第三、第四。。。