我有Unicode字符串,我想与以下要求进行比较。
可混淆的s [1]字符应该被认为是相同的字符, 例如:T(LATIN CAPITAL LETTER T U 0054)应为== T(希腊大写字母TAU U03A4)等
(* [1]示例http://unicode.org/cldr/utility/confusables.jsp?a=TESTt&r=None *)
http://www.unicode.org/Public/security/revision-03/confusablesSummary.txt
我将使用上面的文件来制作代码,但是如果已经有任何免费库我宁愿使用它。
我认为代码会创建一个临时的ustring
,其中每个可混淆的字符都会被相应的拉丁字符替换。
在实际程序中,我将测试10x5000x10000个字符串,每个字符串包含一个单词。
测试程序:
std::locale::global(std::locale(""));
std::cout.imbue(std::locale());
Glib::ustring s1,s2;
s1="TEST";
s2="TΕST";
s1.normalize(Glib::NORMALIZE_NFKD );
s2.normalize(Glib::NORMALIZE_NFKD );
std::cout<<"1->true, 0->false (s1==s2) => "<<(s1==s2)<<"\n";
测试程序输出:
1->true, 0->false (s1==s2) => 0
Ubuntu 区域设置命令输出:
Ubuntu 12.04 64 bit>$ locale
LANG=en_US.UTF-8
LANGUAGE=
LC_CTYPE="en_US.UTF-8"
LC_NUMERIC="en_US.UTF-8"
LC_TIME="en_US.UTF-8"
LC_COLLATE="en_US.UTF-8"
LC_MONETARY="en_US.UTF-8"
LC_MESSAGES="en_US.UTF-8"
LC_PAPER="en_US.UTF-8"
LC_NAME="en_US.UTF-8"
LC_ADDRESS="en_US.UTF-8"
LC_TELEPHONE="en_US.UTF-8"
LC_MEASUREMENT="en_US.UTF-8"
LC_IDENTIFICATION="en_US.UTF-8"
LC_ALL=
感谢您的时间!
答案 0 :(得分:2)
正如user1675224所说,你应该使用ICU,而不是试图推出自己的算法。
例如,要使用uspoof_areConfusable
:
UErrorCode status = 0;
USpoofChecker *sc = uspoof_open(&status);
int result = uspoof_areConfusable(sc, s1.data(), s1.length(), s2.data(), s2.length(), &status);
uspoof_close(sc);
如果您要将大量字符串相互比较,则应使用uspoof_getSkeleton
将它们转换为骨架,并将其放入集合或哈希集中。
答案 1 :(得分:0)
std::string s1,s2;
s1="TEst";
s2="TΕst";
std::cout<<" s1.length()="<<s1.length()<<"\n";
std::cout<<" s2.length()="<<s2.length()<<"\n";
UErrorCode status = U_ZERO_ERROR ;
USpoofChecker *sc = uspoof_open(&status);
char p[100];
int result = uspoof_getSkeletonUTF8 (sc,USPOOF_ANY_CASE, s1.data(),s1.length(),p,100,&status);
std::string skeleton1(p,result);
std::cout<<" result in bytes="<<result<<" status="<<status<<"\n";
std::cout<<" skeleton1="<<skeleton1<<"\n";
std::cout<<"1->true, 0->false (s1==skeleton1) => "<<(s1==skeleton1)<<"\n";
//
char p2[100];
int result2 = uspoof_getSkeletonUTF8 (sc,USPOOF_ANY_CASE , s2.data(),s2.length(),p2,100,&status);
std::string skeleton2(p2,result2);
std::cout<<" result2 in bytes="<<result2<<" status="<<status<<"\n";
std::cout<<" skeleton2="<<skeleton2<<"\n";
std::cout<<"1->true, 0->false (s2==skeleton2) => "<<(s2==skeleton2)<<"\n";
std::cout<<"1->true, 0->false (s1==s2) => "<<(s1==s2)<<"\n";
std::cout<<"1->true, 0->false (skeleton1==skeleton2) => "<<(skeleton1==skeleton2)<<"\n";
//
uspoof_close(sc);
输出
s1.length()=4
s2.length()=5
result in bytes=4 status=0
skeleton1=TEst
1->true, 0->false (s1==skeleton1) => 1
result2 in bytes=4 status=0
skeleton2=TEst
1->true, 0->false (s2==skeleton2) => 0
1->true, 0->false (s1==s2) => 0
1->true, 0->false (skeleton1==skeleton2) => 1
谢谢。