如何使用十六进制值比较字符串对象和文字
How to Compare between String object and literal using hex values
下面显示的代码使用 NTLM Windows 身份验证方法从系统获取用户名,我需要比较用户名 (current_user_eid)。
对预设值应用 intern() 方法似乎适用于初始化值。
文字字符串和对象字符串之间的字符串比较给出了错误的输出,但在屏幕上它们给出了相同的输出。
<%@ 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");
}
}
%>
谁能帮我解决这个问题?
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) H
ere name1 和 name2 都是文字。所以比较是正确的。
2) name3 是对象,但我们使用的是 intern() 因此将获取将作为文字存储在 name4 中的对象的值。所以比较将为真。
3) 但 name3 和 name4 的比较将为 False。因为 name3 是对象而 name4 是文字。但如果您使用 .equals() 则为真。
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 source/java 编译器编码的 EBCDIC 在 AS/400 上工作)。
然而我看到current_user_eid
被分配了两次,第一次是6个字节,这可能对应于"yaseer"是6个字母。
所以我假设第二个 current_user_eid
是一个混淆。
为其值转储字符串:
System.out.println(Arrays.toString(eid_str_in.toCharArray()));
对于其余部分:.intern()
不再使用 w.r.t。效率;因此也不是 ==
。在早期版本中,驻留常量变为 "permanent memory generation" 大小有限,如果驻留过多且过于频繁,这有其缺点。
字节总是被转换为 Unicode String
的 char
s (UTF-16),可能使用平台默认字符集。因此,最好明确提供 Charset
,甚至 Charset.defaultCharset()
,因为它明确说明了平台依赖性。
下面显示的代码使用 NTLM Windows 身份验证方法从系统获取用户名,我需要比较用户名 (current_user_eid)。
对预设值应用 intern() 方法似乎适用于初始化值。
文字字符串和对象字符串之间的字符串比较给出了错误的输出,但在屏幕上它们给出了相同的输出。
<%@ 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");
}
}
%>
谁能帮我解决这个问题?
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) H ere name1 和 name2 都是文字。所以比较是正确的。
2) name3 是对象,但我们使用的是 intern() 因此将获取将作为文字存储在 name4 中的对象的值。所以比较将为真。
3) 但 name3 和 name4 的比较将为 False。因为 name3 是对象而 name4 是文字。但如果您使用 .equals() 则为真。
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 source/java 编译器编码的 EBCDIC 在 AS/400 上工作)。
然而我看到current_user_eid
被分配了两次,第一次是6个字节,这可能对应于"yaseer"是6个字母。
所以我假设第二个 current_user_eid
是一个混淆。
为其值转储字符串:
System.out.println(Arrays.toString(eid_str_in.toCharArray()));
对于其余部分:.intern()
不再使用 w.r.t。效率;因此也不是 ==
。在早期版本中,驻留常量变为 "permanent memory generation" 大小有限,如果驻留过多且过于频繁,这有其缺点。
字节总是被转换为 Unicode String
的 char
s (UTF-16),可能使用平台默认字符集。因此,最好明确提供 Charset
,甚至 Charset.defaultCharset()
,因为它明确说明了平台依赖性。