我目前正在尝试将 NX 的密码加扰算法从 QT-C++ 移植到 C#。
来源: http ://www.nomachine.com/ar/view.php?ar_id=AR01C00125
我目前的代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace mynamespace
{
class NxScramble
{
string ToScramble = "";
int numValidCharList = 85;
String dummyString = "{{{{";
char[] validCharList = new char[]
{
'!', '#', '$', '%', '&', '(', ')', '*', '+', '-',
'.', '0', '1', '2', '3', '4', '5', '6', '7', '8',
'9', ':', ';', '<', '>', '?', '@', 'A', 'B', 'C',
'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
'X', 'Y', 'Z', '[', ']', '_', 'a', 'b', 'c', 'd',
'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x',
'y', 'z', '{', '|', '}'
};
public NxScramble(string s)
{
ToScramble = s;
}
public string scrambleString()
{
string sRet = "";
if (ToScramble == null || ToScramble.Equals(""))
{
return ToScramble;
}
string str = encodePassword(ToScramble);
if (str.Length < 32)
{
str += dummyString;
}
for (int iR = (str.Length - 1); iR >= 0; iR--)
{
//
// Reverse string
//
sRet += str.ElementAt(iR);
}
if (sRet.Length < 32)
{
sRet += dummyString;
}
int k = getRandomValidCharFromList();
int l = k + sRet.Length - 2;
sRet.Insert(0, k.ToString());
string retStr = "";
for (int i1 = 1; i1 < sRet.Length; i1++)
{
int j = findCharInList(sRet.ElementAt(i1));
if (j == -1)
{
return ToScramble;
}
int i = (j + l * (i1 + 1)) % validCharList.Length;
/*
* sRet.ref(i1) = validCharList[i];
*/
retStr += validCharList[i];
}
char c = (char)(getRandomValidCharFromList() + 2);
sRet += c;
retStr = retStr.Replace("&", @"&");
retStr = retStr.Replace("\"", @""");
retStr = retStr.Replace("'", @"'");
retStr = retStr.Replace("<", @"<");
retStr = retStr.Replace(">", @">");
return retStr;
}
private string encodePassword(string p)
{
string sPass = ":";
string sTmp = "";
if (p.Equals(""))
{
return "";
}
for (int i = 0; i < p.Length; i++)
{
char c = (char)p.ElementAt(i);
sTmp = String.Format("{0:d}:", (c + i + 1));
sPass += sTmp;
sTmp = "";
}
return sPass;
}
private int findCharInList(char c)
{
int i = -1;
for (int j = 0; j < numValidCharList; j++)
{
if (validCharList[j] == c)
{
i = j;
return i;
}
}
return i;
}
private char getRandomValidCharFromList()
{
int k = DateTime.Now.Second;
return validCharList[k];
}
}
}
它从给定的密码生成一个字符串,并将其添加到 nxclient 的 XML-Config 文件中:
NxScramble nxs = new NxScramble(passPhrase);
string ScambledPass = nxs.scrambleString();
string nxconfig = @"
....
....
<group name='Login' >
<option key='Auth' value='"+ ScambledPass + @"' />
<option key='Guest Mode' value='false' />
<option key='Guest password' value='' />
<option key='Guest username' value='' />
<option key='Login Method' value='nx' />
<option key='Public Key' value='
.........
.........
' />
<option key='User' value='" + username + @"' />
</group>
";
但是 NXClient 一直说“身份验证失败”。所以我很确定我的 C++ 代码的 C#-Port 中一定有错误。特别是我不确定这行原始代码: sRet.ref(i1) = validCharList[i];
我不知道 ref(i1) 在做什么。
如果有人发现我的错误会很好:)
提前致谢