如何使用十六进制值在字符串对象和文字之间进行比较

时间:2018-09-26 10:35:18

标签: java jsp ntlm

下面显示的代码使用NTLM Windows身份验证方法从系统获取用户名,我需要比较用户名(current_user_eid)。

将intern()方法应用于预设值似乎适用于初始化值。

文字字符串和对象字符串之间的String比较使我得到false作为输出,但在屏幕上它们给出了相同的输出。

<%@ page import="sun.misc.BASE64Encoder" %>
<%
String auth = request.getHeader("Authorization");
String current_user_eid= null;
if (auth == null) {
        response.setStatus(response.SC_UNAUTHORIZED);
        response.setHeader("WWW-Authenticate", "NTLM");
        return;
}
if (auth.startsWith("NTLM")) { 
    byte[] msg = new sun.misc.BASE64Decoder().decodeBuffer(auth.substring(5));
    int off = 0, length, offset;

    if (msg[8] == 1) { 
        off = 18;
        byte z = 0;
        byte[] msg1 =
            {(byte)'N', (byte)'T', (byte)'L', (byte)'M', (byte)'S',
            (byte)'S', (byte)'P', z,
            (byte)2, z, z, z, z, z, z, z,
            (byte)40, z, z, z, (byte)1, (byte)130, z, z,
            z, (byte)2, (byte)2, (byte)2, z, z, z, z, // 
            z, z, z, z, z, z, z, z};

        response.setStatus(response.SC_UNAUTHORIZED);
        response.setHeader("WWW-Authenticate", "NTLM " + new sun.misc.BASE64Encoder().encodeBuffer(msg1).trim());
        return;
    } 
    else if (msg[8] == 3) { 
        off = 30;
        length = msg[off+17]*256 + msg[off+16];
        offset = msg[off+19]*256 + msg[off+18];
        current_user_eid = new String(msg, offset, length);
    } 
    else
        return;

    length = msg[off+1]*256 + msg[off];
    offset = msg[off+3]*256 + msg[off+2];
    current_user_eid = new String(msg, offset, length);
    length = msg[off+9]*256 + msg[off+8];
    offset = msg[off+11]*256 + msg[off+10];
    current_user_eid = new String(msg, offset, length); //current system user name "yaseer"

    // String Comparison starts here....

    String hard_str = new String("yaseer"); // 
    String hard_str_in=hard_str.intern();

    String eid_str=new String(current_user_eid.toString()); //passing the fetched username which is yaseer
    String eid_str_in = eid_str.intern(); // system username 

    String comp_str = "yaseer"; // String for comparison

    System.out.println(hard_str_in == comp_str); // give true

    System.out.println(eid_str_in == comp_str); // gives false


if(eid_str_in .equals(comp_str ))
{
    System.out.println("true");
}
else
{
    System.out.println("false");
}
}
%>

有人可以帮助我解决这个问题吗?

2 个答案:

答案 0 :(得分:1)

1)字符串文字将存储在字符串常量池中。此处的值不能重复。例如,如果您尝试创建两个具有相同值的变量,则第二个变量值不能存储在SCP中,而是将获取第一个值地址。

2)但是,即使两个对象具有相同的值,也将使用 new String 创建两个对象。

示例:

public class TestFile {

    public static void main(String[] args) {
        String name1 = "AAA";
        String name2 = name1.intern();

        String name3 = new String("AAA");
        String name4 = name3.intern();

        System.out.println(name1 == name2); // true
        System.out.println(name2 == name4); // true

        System.out.println(name3 == name4); // false
        System.out.println(name3.equals(name4));
    }   
}

1)高 name1和name2都是文字。因此比较结果为True。

2)name3是对象,但我们使用的是intern(),因此将获取该对象的值,该值将作为文字存储在name4中。所以比较会是真的。

3)但是name3和name4对应将为False。因为name3是对象,而name4是文字。但是,如果您使用的是.equals(),它将是正确的。

答案 1 :(得分:1)

关于String的正确用法是:

Charset charset = StandardCharsets.ISO_8859_1;
...
    current_user_eid = new String(msg, offset, length, charset);
} 
else
    return;

length = msg[off+1]*256 + msg[off];
offset = msg[off+3]*256 + msg[off+2];
current_user_eid = new String(msg, offset, length, charset);
length = msg[off+9]*256 + msg[off+8];
offset = msg[off+11]*256 + msg[off+10];
current_user_eid = new String(msg, offset, length, charset);
//current system user name "yaseer"

// String Comparison starts here....

String hard_str = "yaseer"; // 

String eid_str = current_user_eid; //passing the fetched username which is yaseer
String eid_str_in = eid_str.intern(); // system username 

String comp_str = "yaseer"; // String for comparison

System.out.println(hard_str_in == comp_str); // give true

System.out.println(eid_str_in == comp_str); // gives false
System.out.println(eid_str_in.equals(comp_str));
// gave true ("on screen"), expected to give false

如果我正确理解你的话,最后两行会给出不同的结果。

对于纯ASCII“ yaseer”,情况并非如此(假设您无法在带有错误的Java源代码/ Java编译器编码的EBCDIC的AS / 400上工作)。

但是我看到current_user_eid被分配了两次,第一次是6字节,这可能对应于带有6个字母的“ yaseer”。

所以我认为第二个current_user_eid是一个混乱的地方。

转储字符串的值:

System.out.println(Arrays.toString(eid_str_in.toCharArray()));

其余部分:.intern()不再需要使用。效率;因此也不是==。在较早的版本中,内联常数用于有限大小的“永久内存生成”,如果过多和过多地进行内联,则存在缺点。

总是使用平台默认的字符集将字节转换为Unicode String的{​​{1}}(UTF-16)。因此最好显式提供char,甚至提供Charset,因为这样可以显式说明平台依赖性。