Java 如何确定字符串是否为散列

Java 如何确定字符串是否为散列,java,cryptography,Java,Cryptography,我必须实现一个Java方法,它将确定输入字符串是散列(由机器生成)还是纯文本(由人编写) 例如: isThisEncrypted("qwertyuiopasdfghjklzxcvbnm"); // returns true isThisEncrypted("some normal human text"); // returns false 我考虑过使用Kolmogorov-Smirnov测试(jsc.goodnessfit.KolmogorovTest),它将检查字符串中的字符是否来自正态分

我必须实现一个Java方法,它将确定输入字符串是散列(由机器生成)还是纯文本(由人编写)

例如:

isThisEncrypted("qwertyuiopasdfghjklzxcvbnm"); // returns true
isThisEncrypted("some normal human text"); // returns false
我考虑过使用Kolmogorov-Smirnov测试(jsc.goodnessfit.KolmogorovTest),它将检查字符串中的字符是否来自正态分布,但我了解到,仅检查一个短字符串可能不是决定性的


您知道如何用Java解决这个问题吗(最好使用现有的库)?

您将输入拆分为单词,并对照字典()进行检查

从现在起,一切都取决于您的实施。依我看,如果有一半的单词与字典匹配,那么你的方法应该返回false

根据您的评论:

人的输入可以是随机的

此方法必须确定字符串是否来自此方法或表单 使用者

那么就没有办法解决你的问题,只有字符串。你需要额外的信息


如果您希望河豚以给定的格式返回字符串,那么您就错了。现代加密算法的目标是高熵,这意味着它们看起来和感觉都是随机的。

您已经说过,您只想要一个近似的解决方案(80%的准确率),AClassName形式的类很可能是(注意大写),并且给定的加密文本样本中没有大写字母。所以

public class Test{

    public static void main(String args[]){
        String[] tests=new String[5];

        tests[0]="MyClass";
        tests[1]="Short";
        tests[2]="thsrjtyzfgnmytkzrhjstk";
        tests[3]="tatm";
        tests[4]="The result is good";

        for(int i=0;i<tests.length;i++){
            System.out.println(tests[i]+ "- Encrypted:" + isProbablyEncrypted(tests[i]));
        }


    }

    public static boolean isProbablyEncrypted(String in){
        int noOfWords= countOccurrences(in, ' ') + countCaps(in);
        if (noOfWords==0){
            return true;
        }else{
            double averageWordLength=(double)(in.length())/(noOfWords+1);

            if (averageWordLength>15){
                return true;
            }else{
                return false;
            }
        }
    }

    public static int countOccurrences(String haystack, char needle)
    {
        int count = 0;
        for (int i=0; i < haystack.length(); i++)
        {
            if (haystack.charAt(i) == needle)
            {
                 count++;
            }
        }
        return count;
    }

    public static int countCaps(String in){
        int caps=0;
        for (int i=0; i<in.length(); i++) {
            if (Character.isUpperCase(in.charAt(i)))caps++;
        }
        return caps;
    }
}
公共类测试{
公共静态void main(字符串参数[]){
字符串[]测试=新字符串[5];
测试[0]=“MyClass”;
测试[1]=“短”;
测试[2]=“thsrjtyzfgnmytkzrhjstk”;
测试[3]=“tatm”;
测试[4]=“结果良好”;
对于(int i=0;i15){
返回true;
}否则{
返回false;
}
}
}
公共静态整数计数(字符串干草堆、字符针)
{
整数计数=0;
对于(int i=0;i对于(int i=0;i80%准确度;是的

这整件事看起来很危险,一个Algortim可能只是碰巧生成一个看起来像人的字符串。你是否控制哈希函数,用户输入是否总是有几个词?我知道,这不是一个oracle,大约80%的准确度就足够了。好吧,根据场景和算法,你可以选择t表示哈希长度(如果algo产生恒定长度输出),您也可以检查空格。但是,这不是一个完整的证明策略,您需要找到解决方法,正确的方法是将哈希与存储的明文的哈希进行比较。此链接与您的问题不同,但可能会有帮助。哈希和加密是两件不同的事情。您将生成哪一件?我不期望Blowfish以给定的格式返回字符串。我希望它是随机的。所谓人工输入可以是随机的,我的意思是,它可以是一个单词、几个单词,或者是从几个单词中新建或创建的。这个方法必须告诉我,输入是否明显是随机字符串(例如“edgyewfduysfd”)或“humanish”(例如“BusinessLogicCoreClass”)。这就是为什么我的第一个gues是检查输入字符串的正态分布。我要再说一遍:这个方法不必是oracle,80%的准确率将是enaugh:)(它的结果只是一个提示)@user2265495 80%的准确率;检查单词长度,假设算法甚至在其中加入空格,那么它们将在27次中出现1次,而我预计英语语言将在5或6次中出现1次。一个单词:可能不到20%的时间,许多单词没有空格:多久出现一次happen@Richard-不幸的是,许多没有空格的单词可能频繁出现在这种情况下,由于KNIME节点将加密和解密类名(以及其他内容)。因此类似于“BusinessLogicCoreClass”的字符串将是该节点非常正常的输入。@user2265495:“如果输入明显是随机字符串(例如“edgyewfduysfd”)或“humanish”(例如“BusinessLogicCoreClass”),则此方法必须告诉我。”然后你必须计算它的熵,但我的观点是,人类可以提供一个随机的字符串来愚弄这个方法(字符串越短,愚弄的可能性越大)。可能Richard的答案是你能得到的最接近的答案。唯一失败的是一个单词的句子不属于类别。我假设你以后检查加密是否冗长且昂贵?如果加密文本可以以50%的概率包含大写字母,那么非常短的平均单词分数也意味着加密