2014-09-23 15 views
23

Mam następujący kod C# (z biblioteki, której używam), który próbuje znaleźć certyfikat porównujący odcisk kciuka. Zauważ, że w poniższym kodzie są zarówno ciągi znaków, jak i mycert.Thumbprint i certificateThumbprint.Dlaczego String.Equals zwraca wartość false?

var certificateThumbprint = AppSettings.CertificateThumbprint; 

var cert = 
    myStore.Certificates.OfType<X509Certificate2>().FirstOrDefault(
     mycert => 
     mycert.Thumbprint != null && mycert.Thumbprint.Equals(certificateThumbprint) 
    ); 

ten nie znajdzie się certyfikat z odciskiem palca bo mycert.Thumbprint.Equals(certificateThumbprint) jest false nawet gdy łańcuchy są równe. mycert.Thumbprint == certificateThumbprint zwraca również false, natomiast mycert.Thumbprint.CompareTo(certificateThumbprint) zwraca 0.

enter image description here

I może być brakuje czegoś oczywiste, ale nie mogę zrozumieć, dlaczego metoda Equals zawodzi. Pomysły?

+15

To może być dziwne pytanie ... ale czy długości są takie same na każdym sznurku?(próbując sprawdzić, czy w jakiś sposób są tam jakieś niedrukowalne znaki). – vcsjones

+5

Z plików ['string.CompareTo'] (http://msdn.microsoft.com/en-us/library/fkw3h78a (v = vs.110) .aspx) docs: * Zestawy znaków ** zawierają niedozwolone znaki. * * Metoda CompareTo nie uwzględnia takich znaków, gdy dokonuje porównania wrażliwego na kulturę. Na przykład, jeśli poniższy kod zostanie uruchomiony w .NET Framework 4 lub nowszym, porównanie "animal" z "ani-mal" (za pomocą miękkiego łącznika, lub U + 00AD) wskazuje, że dwa ciągi są równoważne. * –

+2

@Yuval Twój cytat zdaje się sugerować przeciwieństwo tego, co podejrzewa vcsjones. –

Odpowiedz

21

CompareTo ignoruje pewne znaki:

static void Main(string[] args) 
{ 
    var a = "asdas"+(char)847;//add a hidden character 
    var b = "asdas"; 
    Console.WriteLine(a.Equals(b)); //false 
    Console.WriteLine(a.CompareTo(b)); //0 
    Console.WriteLine(a.Length); //6 
    Console.WriteLine(b.Length); //5 

    //watch window shows both a and b as "asdas" 
} 

(Tu, postać dodany do a jest U+034F, łącząc grafemów.)

Debug mode

Więc wynik CompareTo nie jest dobrym wskaźnikiem błąd w Equals. Najbardziej prawdopodobną przyczyną problemu są ukryte postacie. Możesz sprawdzić długości, aby mieć pewność.

Aby uzyskać więcej informacji, zobacz this.

+0

Rzeczywiście, miałem dwa znaki U + 200E (od lewej do prawej) na początku ciągu 'certificateThumbprint'. Usunięcie to naprawiło problem. –

+0

Ze wszystkich odpowiedzi jest to poprawna. Istnieją również komentarze, które wskazywały również na poprawny problem, w tym link do tego pytania http://stackoverflow.com/questions/11115511/how-to-find-certificate-by-its-thumbprint-in-c- sharp. Zaznaczę to jako zaakceptowaną odpowiedź. Żałuję, że nie mogę tego zrobić również dla komentarzy. –

2

Możesz spróbować użyć przeciążenia z String.Equals, które akceptuje parametr typu StringComparison.

Na przykład:

myCert.Thumbprint.Equals(certificateThumbprint, StringComparison.[SomeEnumeration]) 


Gdzie [SomeEnumeration] otrzymuje jedną z następujących stałych wyliczeniowych:

- CurrentCulture 
- CurrentCultureIgnoreCase 
- InvariantCulture 
- InvariantCultureIgnoreCase 
- Ordinal 
- OrdinalIgnoreCase 


Reference dokumentacji MSDN znaleźć here. enter image description here

+0

Próbowałem z 'OrdinalIgnoreCase', a wynik był taki sam (tj. False). –

0

Czasami, kiedy wstawić dane w bazie danych przechowuje pewne przestrzenie jak „pytanie”. A kiedy spróbujesz porównać to z "pytanie", zwróci false. Moja sugestia brzmi: sprawdź wartość w bazie danych lub użyj metody Trim().

w Twoim przypadku, spróbuj: mycert.Thumbprint = null & & mycert.Thumbprint.trim() jest równa (certificateThumbprint.trim())

myślę zwróci true, jeśli każdy!. rekord będzie istnieć.