Bez przesyłania, 100% lokalnie, bez konta

Artykuł

Porównywanie fragmentów kodu bez ich przesyłania

Za każdym razem, gdy wklejasz dwa pliki do internetowego narzędzia diff, kod opuszcza Twój komputer. Pliki konfiguracyjne, zapytania do bazy danych, klucze API ukryte we fragmencie .env: wszystko to trafia na serwer, nad którym nie masz kontroli. Ten artykuł omawia, jak działają algorytmy diff, co oznaczają opcje szczegółowości w praktyce i dlaczego ważne jest, aby porównanie pozostało lokalne.

Co oblicza diff

Narzędzie diff pobiera dwa teksty i znajduje minimalny zestaw zmian, które przekształcają jeden w drugi. Podstawową ideą jest najdłuższa wspólna podciąg, czyli LCS: najdłuższa sekwencja linii (lub tokenów), która pojawia się w obu tekstach w tej samej kolejności, nawet jeśli nie sąsiadują ze sobą. Wszystko, co nie należy do tej wspólnej podciągu, to albo dodanie w nowej wersji, albo usunięcie ze starej. Klasyczny algorytm do tego celu pochodzi od Myersa (1986), który znajduje najkrótszy skrypt edycji w czasie O((N+M)D), gdzie N i M to długości dwóch tekstów, a D to liczba edycji. W praktyce większość narzędzi dodaje krok wstępnego przetwarzania, aby zignorować wspólne linie wiodące i końcowe, redukując problem do zmienionego obszaru. Wynikiem jest łatka: sekwencja porcji, z których każda opisuje ciągły blok linii kontekstowych, usunięć i dodań. To format używany przez Unix diff, Git i większość narzędzi do przeglądu kodu.

Diagram przedstawiający dwa teksty wejściowe wyrównane według najdłuższej wspólnej podciągu, z połączonymi pasującymi liniami i liniami różniącymi się oznaczonymi jako dodania lub usunięcia

Szczegółowość liniowa, słowna i znakowa

Szczegółowość diff określa, co jest jednostką porównania. Diff liniowy jest domyślny w większości narzędzi: każda linia jest traktowana jako jeden token. Jest szybki i daje wynik, który jest łatwy do odczytania w kontekście, ale oznacza całą linię jako zmienioną, nawet jeśli zmieniło się tylko jedno słowo w tej linii. Diff na poziomie słów dzieli każdą linię na słowa przed uruchomieniem LCS. Daje to dokładniejszy obraz tego, co zmieniło się w linii, co jest przydatne dla tekstu narracyjnego, wartości konfiguracyjnych lub JSON. Diff na poziomie znaków idzie dalej i może wyróżnić pojedynczą zmienioną literę wewnątrz długiego identyfikatora. Obsługa białych znaków dodaje szum. Linia kończąca się CRLF i ta sama linia kończąca się LF będą wyglądać jako różne przy ścisłym porównaniu bajtów. Większość narzędzi oferuje flagę normalizacji końców linii przed porównaniem. Podobnie końcowe spacje, wcięcia tabulatorem kontra spacjami i puste linie mogą generować fałszywy wynik diff. Włączenie normalizacji białych znaków jest zazwyczaj właściwym domyślnym ustawieniem przy porównywaniu kodu z różnych edytorów lub systemów operacyjnych.

Ryzyko dla prywatności przy używaniu internetowych narzędzi diff

Internetowe usługi diff i pastebin są wygodne: otwierasz URL, wklejasz dwa fragmenty, otrzymujesz kolorowy wynik. Problem polega na tym, że wklejany tekst jest przesyłany na serwer strony trzeciej. W zależności od usługi tekst może być logowany, indeksowany, przechowywany bezterminowo lub udostępniany dostawcom analityki. Ma to największe znaczenie, gdy kod zawiera wrażliwe materiały. Zakodowane na twardo dane uwierzytelniające, wewnętrzne nazwy hostów, zastrzeżona logika biznesowa lub dane osobowe mogą trafić do wklejki. Nawet bez jawnych tajemnic struktura wewnętrznego kodu może ujawniać decyzje architektoniczne, które wolałbyś zachować w tajemnicy. Ryzyko nie jest hipotetyczne. Badacze bezpieczeństwa wielokrotnie znajdowali dane uwierzytelniające i wewnętrzne tokeny w publicznych wklejkach. Niektóre usługi zachowują wklejki nawet po ich usunięciu przez użytkownika, ponieważ kopie istnieją w pamięciach podręcznych lub kopiach zapasowych. Nie ma możliwości sprawdzenia, co zdalna usługa robi z tekstem po jego dotarciu. Jedynym niezawodnym środkiem zaradczym jest utrzymanie diff lokalnie, co oznacza uruchomienie go w narzędziu, które nigdy nie wysyła tekstu przez sieć.

Zrzut ekranu panelu sieciowego przeglądarki pokazujący zero wychodzących żądań podczas porównywania dwóch fragmentów kodu w narzędziu text-diff

Praktyczne zastosowania lokalnego diff

Diff nie służy tylko do przeglądu kodu. Kilka typowych przypadków, w których lokalny diff jest przydatny: Przeglądanie zmian w dokumencie lub pliku konfiguracyjnym przed zatwierdzeniem. Porównywanie dwóch wersji Dockerfile, konfiguracji Nginx lub manifestu Kubernetes, aby dokładnie zrozumieć, co zmieniło się między wdrożeniami. Sprawdzanie dryfu konfiguracji między środowiskami. Jeśli konfiguracje produkcji i środowiska testowego mają być identyczne poza nazwami hostów i tajemnicami, diff natychmiast pokazuje każdą niezamierzoną rozbieżność. Porównywanie odpowiedzi API podczas debugowania. Wklejenie dwóch ładunków JSON z REST lub GraphQL API i uruchomienie diff na poziomie słów wskazuje dodane pola, zmienione wartości lub usunięte klucze bez ręcznego przeglądania setek linii. Przeglądanie kodu wygenerowanego przez model językowy w porównaniu z punktem odniesienia. Gdy model przepisuje funkcję, diff liniowy pokazuje, która logika się zmieniła, a która pozostała taka sama, szybciej niż niezależne czytanie obu wersji. We wszystkich tych przypadkach zaangażowany tekst może być wrażliwy, a utrzymanie go z dala od zdalnego serwera jest oczywistym wyborem.

W przeglądarce, bez przesyłania

Narzędzie text-diff na tej stronie wykonuje całe obliczenia diff w przeglądarce przy użyciu JavaScript. Wklejasz dwa teksty do dwóch paneli, a diff renderuje się natychmiast, linia po linii, do 3000 linii na stronę. Nic nie jest wysyłane na serwer. Tekst nigdy nie opuszcza urządzenia. Implementacja używa standardowego algorytmu opartego na LCS działającego na liniach: każda linia jest tokenem, a narzędzie ustala, czy jest niezmieniona, dodana czy usunięta, znajdując najdłuższy wspólny podciąg między dwiema wersjami. Niezmienione linie renderowane są bez wyróżnienia, dodane na zielono, usunięte na czerwono, obok bieżącego licznika dodań i usunięć. Obecnie nie ma trybu na poziomie słów ani znaków, ani przełącznika normalizacji białych znaków, więc linia różniąca się tylko końcowymi białymi znakami lub stylem zakończenia linii nadal pokazuje się jako zmieniona. Ponieważ obliczenia działają po stronie klienta, działają offline. Nie ma konta, historii ani przechowywania. Możesz porównać lokalny plik konfiguracyjny z szablonem, przejrzeć łatkę przed jej zastosowaniem lub sprawdzić dwie odpowiedzi API bez przesyłania tego tekstu do strony trzeciej.

Narzędzia w tym artykule

Najczęściej zadawane pytania

Czy diff liniowy czy słowny jest lepszy do kodu?

Dla większości zadań przeglądu kodu diff liniowy jest standardem i najłatwiejszy do odczytania, ponieważ kod jest ustrukturyzowany wierszami. Diff słowny mógłby pomóc, gdy linie są długie i zmieniła się tylko niewielka ich część, np. w jednowierszowej wartości JSON, ale to narzędzie porównuje wyłącznie na poziomie linii; w takim przypadku potraktuj podświetloną linię jako wskazówkę i wypatrz mniejszą różnicę w jej wnętrzu.

Dlaczego internetowe narzędzia diff stanowią zagrożenie dla prywatności, nawet jeśli używają HTTPS?

HTTPS chroni tekst podczas transmisji przed podsłuchem, ale nie chroni go po dotarciu na serwer. Operator usługi ma pełny dostęp do wklejonej treści i może ją logować, przechowywać lub udostępniać. TLS dotyczy bezpieczeństwa transportu, a nie tego, co odbiorca robi z danymi.

Czy narzędzie text-diff przechowuje historię poprzednich porównań?

Nie. Narzędzie nie ma zaplecza i nie wysyła żadnych żądań sieciowych. Po zamknięciu lub przeładowaniu karty tekst znika. Nie ma konta, zapisanej historii ani dziennika po stronie serwera.