c++Unicode字符串与易混淆字符的比较.例如(U 0054)应为==(U03A4)等



我有Unicode字符串,我想与以下要求进行比较。

可混淆的s[1]字符应该被认为是相同的字符,例如:T(拉丁大写字母T U 0054)应等于T(希腊大写字母TAU U03A4)等

(*[1]示例http://unicode.org/cldr/utility/confusables.jsp?a=TESTt&r=无*)

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=

感谢您抽出时间

正如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将它们转换为其骨架,并将其放入集合或哈希集中。

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

谢谢。

相关内容

最新更新