Substring w szyfrze - problem

Substring w szyfrze - problem
FR
  • Rejestracja:około 14 lat
  • Ostatnio:ponad 10 lat
  • Postów:40
0

Witam
Ostatnio przerzucam się na C++ (w Visual Studio) i teraz staram się napisać aplikację do szyfrowania. Mam problem z szyfrem Bacona a dokładnie z jego deszyfracją. Krótko mówiąc polega on na zamianie konkretnych liter w ciągi złożone z 'a' i 'b' np. "a" -> "aaaaa", "b" -> "aaaab" itp. Znaki poza literami pozostają nie zmienione.

O ile szyfrowanie poszło mi dość dobrze to mam problem jak to odczytać. Moja koncepcja, aby sprawdzać 5 znaków z wszystkimi możliwymi kombinacjami oznaczającymi litery nie chce działać. Kompiluje się, ale nawet próba odszyfrowania "aaaaa" wyrzuca komunikat błędu, który [jak mi się wydaje] mówi o przekroczeniu tablicy.

Fragment kodu, który za to odpowiada (na razie tylko litery a i b oraz inne znaki uwzględniłem - chciałem switch'em ale nie obsługuje string'ów):

Kopiuj
{
richTextBox1->Text = ""; //czyszczenie miejsca zapisania rozszyfrowanego kodu
System::String^ tekscik = richTextBox2->Text;
int dl = tekscik->Length;
System::String^ frag;
for (int i=0; i<dl;)
        {
	frag = tekscik->Substring(i, 5);
	if (frag == "aaaaa") {richTextBox1->Text += "a"; i=i+5;}
	if (frag == "aaaab") {richTextBox1->Text += "b"; i=i+5;} else {richTextBox1->Text += tekscik[i].ToString(); i=i+1;}
	}
		 } 
edytowany 2x, ostatnio: franiis
Azarien
  • Rejestracja:ponad 21 lat
  • Ostatnio:około 7 godzin
0

tak na szybko, wszystkie twoje napisy powinny być unikodowe, tj. L"aaaaa"
Zawsze gdy używasz String^, literał powinien być z L przed cudzysłowem.

edytowany 1x, ostatnio: Azarien
FR
  • Rejestracja:około 14 lat
  • Ostatnio:ponad 10 lat
  • Postów:40
0
Kopiuj
if (frag == L"aaaaa") {richTextBox1->Text += "a"; i=i+5;}
if (frag == L"aaaab") {richTextBox1->Text += "b"; i=i+5;} 

Jeśli dobrze rozumiem chodzi o coś takiego. Ale nie wyklucza to wcześniejszego błędu :/

Azarien
  • Rejestracja:ponad 21 lat
  • Ostatnio:około 7 godzin
1
Kopiuj
frag = tekscik->Substring(i, 5);

Pobierasz pięć znaków począwszy od pozycji i, a przecież wcale nie musi być tyle liter pozostałych (np. na ostatniej pozycji jest tylko jedna), a nawet cały napis może być krótszy niż pięć znaków.

FR
No zgadza się. To wiedziałem, ale nie tłumaczy to dlaczego: 1) Wywala się przy próbie odszyfrowania "aaaaa", 2) wywala się nawet po dodaniu zapisu, że jeśli dl-i<5 to przepisz końcówkę i zwiększ 'i' o 10(aby wyszedł z pętli)... Nie wiem ciągle jak to poprawić :/ Ale dzięki za wskazówki :)
FR
  • Rejestracja:około 14 lat
  • Ostatnio:ponad 10 lat
  • Postów:40
0

Po uwzględnieniu porad Azarien'a (dziękuję) udaje się odszyfrować pewne ciągi, ale to nie jest działa jak powinno. (Nie zauważyłem różnicy 'unicodowych' ciągów, ani takie nie działają, ani drugie)

Kod wygląda teraz następująco:

Kopiuj
System::String^ tekscik = richTextBox2->Text + "^"; // ((1))
int dl = tekscik->Length;
System::String^ frag;
for (int i=0; i<dl;)
{
if (dl>=i+5)
{
frag = tekscik->Substring(i, 5);
if (frag == L"aaaaa") {richTextBox1->Text += "a"; i=i+5;}
if (frag == L"aaaab") {richTextBox1->Text += "b"; i=i+5;}
if (frag == L"aaaba") {richTextBox1->Text += "c"; i=i+5;}
if (frag == L"aaabb") {richTextBox1->Text += "d"; i=i+5;}
//[....] kolejne znaki i ich kody
if (frag == L"BABBA") {richTextBox1->Text += "Y"; i=i+5;}
if (frag == L"BABBB") {richTextBox1->Text += "Z"; i=i+5;} else {richTextBox1->Text += tekscik[i].ToString(); i=i+1;}
}
else {richTextBox1->Text += tekscik[i].ToString(); i=i+1;}
}
 

Problemy jakie teraz z tym mam to następujące:

  1. Rozkodowywanie ciągu "aaaaa" jest niemożliwe, jako, że wyrzuca błąd odwoływania się za tablicę. poradziłem sobie 'partyzancko' - ((1))
  2. Zaszyfrowanie (które działa) 4 znaków "a", a potem ich rozkodowanie daje "aaaaaaaaa" (9 x "a", czyli rozkodował tylko 3 ciągi).
  3. Zakodowanie "szyfr", a potem jego rozkodowanie daje wynik "sbqabsabr", natomiast zaszyfrowanie "s z y f r" i jego odkodowanie daje dobry efekt.

Wydaje mi się, że są to już tylko błędy logiczne, ale za wszelkie (nawet małe sugestie czy pomysły) będę wdzięczny. :)
Pozdrawiam
Piotrek - franiis

edytowany 2x, ostatnio: franiis
Azarien
  • Rejestracja:ponad 21 lat
  • Ostatnio:około 7 godzin
1

nie tłumaczy to dlaczego: 1) Wywala się przy próbie odszyfrowania "aaaaa"

Ponieważ w pętli jedziesz po całym stringu, to dla stringa takiego:

Ala ma kota
w poszczególnych krokach próbujesz czytać takie 5-literowe podciągi:

Kopiuj
'Ala m'
'la ma'
'a ma '
' ma k'
'ma ko'
'a kot'
' kota'
'kota☠'
'ota☠☠'
'ta☠☠☠'
'a☠☠☠☠'
FR
Choć tak po dłuższym zastanowieniu nie do końca. Ciąg o jakim ja mówię ("aaaaa") jest specjalnie odczytywany w całości i od razu rozpoznany (powinien). Następnie zwiększenie "i" o 5 i już nie powinien wejść w tablicę, więc nie powinien odczytywać elementów z poza tablicy. W założeniach wszystko.
FR
  • Rejestracja:około 14 lat
  • Ostatnio:ponad 10 lat
  • Postów:40
0

To się zgadza. Ale po poprawkach, które opisałem uwzględniam już to. więc wyglądałoby to tak (nie zastosuję zdania, "Ala ma kota" - gdyż nie pasuje):

Tekst: AAAAAdomAAAAAxx

  1. AAAAA - wypisuje "A" i dodaje 5 do przelicznika,
  2. sprawdza domAA, ale że nie ma takiego kodu to wypisuje "d" i dodaje 1 do przelicznika,
  3. sprawdza omAAA, analogicznie jak w 2),
  4. sprawdza mAAAA, analogicznie jak wyżej,
  5. sprawdza AAAAA i wypisuje "A" oraz dodaje 5 po przelicznika.
  6. długość ciągu pomniejszona o aktualne miejsce odczytu jest już mniejsza od 5, więc po prostu przepisuje kolejny znak x (wiem, że nic nie jest tu zakodowane).
  7. analogicznie jak wyżej x

Tak to powinno działać (w moim zamierzeniu), ale coś jest nie tak, jak wcześniej opisałem

adf88
  • Rejestracja:ponad 21 lat
  • Ostatnio:prawie 12 lat
0

Wychodzisz poza zakres tablicy dlatego, że po znalezieniu pasującego wzorca nie przechodzisz do następnego obiegu pętli tylko kontynuujesz kolejne porównania.
Zamień if'y na if..else'y

Kopiuj
if (frag == L"aaaaa") {richTextBox1->Text += "a"; i=i+5;}
else if (frag == L"aaaab") {richTextBox1->Text += "b"; i=i+5; }
else if...

A tak w ogóle to użyj pętli i tablicy czy jakiegoś kontenera zamiast się powtarzać X razy!

Poza tym zamiast sprawdzać zakres wewnątrz pętli:

Kopiuj
for (int i=0; i<dl;)
{
    if (dl>=i+5) ...

powinieneś po prostu iterować po właściwym zakresie:

Kopiuj
for (int i = 0; i + 5 < dl; )
{
    ...

no chyba, że długość wzorców może być różna wtedy trzeba to inaczej rozwiązać.

Jeśli wzorców będzie dużo a chciałbyś przyspieszyć algorytm to do ich przechowywania/wyszukiwania użyj drzewa słownikowego czy hashtablicy np. System::Collections::Generic::HashSet. W przypadku wzorców o różnej długości najbardziej optymalne powinno być drzewo słownikowe, tyle że musiałbyś je sam zaimplementować lub użyć dodatkowej biblioteki.

edytowany 15x, ostatnio: adf88
FR
  • Rejestracja:około 14 lat
  • Ostatnio:ponad 10 lat
  • Postów:40
0

Dzięki wielkie za poradę z "if else" - wszystko działa jak powinno. Co do dalszych pomysłów, to:

  1. Zamiana zakresu for spowoduje, że ostanie znaki, jeśli nie będą kodowane, to je pozostawi nie przenosząc ich do tekstu jawnego.
  2. Długości ciągów wynoszą albo 1 albo 5. Kodowane są tylko 5-cio znakowe. Liczba takich kombinacji to 50-52 (zależnie czy trwa kodowanie czy odkodowywanie). Już mam zapisany tak kod, więc chyba nie potrzebuję zmieniać tego koniecznie. Poza tym średnio 25 porównań to nie jest chyba liczba, która załamie zdolności algorytmu.

Bardzo dziękuję za pomoc :)
Chyba można zamknąć.

adf88
  • Rejestracja:ponad 21 lat
  • Ostatnio:prawie 12 lat
0

ad 1) po prostu dopisz do wyniku resztę która ci zostanie

FR
No tak. Dlatego nie używam pętli for postaci: ^^ for (int i = 0; i + 5 < dl;).
Kliknij, aby dodać treść...

Pomoc 1.18.8

Typografia

Edytor obsługuje składnie Markdown, w której pojedynczy akcent *kursywa* oraz _kursywa_ to pochylenie. Z kolei podwójny akcent **pogrubienie** oraz __pogrubienie__ to pogrubienie. Dodanie znaczników ~~strike~~ to przekreślenie.

Możesz dodać formatowanie komendami , , oraz .

Ponieważ dekoracja podkreślenia jest przeznaczona na linki, markdown nie zawiera specjalnej składni dla podkreślenia. Dlatego by dodać podkreślenie, użyj <u>underline</u>.

Komendy formatujące reagują na skróty klawiszowe: Ctrl+B, Ctrl+I, Ctrl+U oraz Ctrl+S.

Linki

By dodać link w edytorze użyj komendy lub użyj składni [title](link). URL umieszczony w linku lub nawet URL umieszczony bezpośrednio w tekście będzie aktywny i klikalny.

Jeżeli chcesz, możesz samodzielnie dodać link: <a href="link">title</a>.

Wewnętrzne odnośniki

Możesz umieścić odnośnik do wewnętrznej podstrony, używając następującej składni: [[Delphi/Kompendium]] lub [[Delphi/Kompendium|kliknij, aby przejść do kompendium]]. Odnośniki mogą prowadzić do Forum 4programmers.net lub np. do Kompendium.

Wspomnienia użytkowników

By wspomnieć użytkownika forum, wpisz w formularzu znak @. Zobaczysz okienko samouzupełniające nazwy użytkowników. Samouzupełnienie dobierze odpowiedni format wspomnienia, zależnie od tego czy w nazwie użytkownika znajduje się spacja.

Znaczniki HTML

Dozwolone jest używanie niektórych znaczników HTML: <a>, <b>, <i>, <kbd>, <del>, <strong>, <dfn>, <pre>, <blockquote>, <hr/>, <sub>, <sup> oraz <img/>.

Skróty klawiszowe

Dodaj kombinację klawiszy komendą notacji klawiszy lub skrótem klawiszowym Alt+K.

Reprezentuj kombinacje klawiszowe używając taga <kbd>. Oddziel od siebie klawisze znakiem plus, np <kbd>Alt+Tab</kbd>.

Indeks górny oraz dolny

Przykład: wpisując H<sub>2</sub>O i m<sup>2</sup> otrzymasz: H2O i m2.

Składnia Tex

By precyzyjnie wyrazić działanie matematyczne, użyj składni Tex.

<tex>arcctg(x) = argtan(\frac{1}{x}) = arcsin(\frac{1}{\sqrt{1+x^2}})</tex>

Kod źródłowy

Krótkie fragmenty kodu

Wszelkie jednolinijkowe instrukcje języka programowania powinny być zawarte pomiędzy obróconymi apostrofami: `kod instrukcji` lub ``console.log(`string`);``.

Kod wielolinijkowy

Dodaj fragment kodu komendą . Fragmenty kodu zajmujące całą lub więcej linijek powinny być umieszczone w wielolinijkowym fragmencie kodu. Znaczniki ``` lub ~~~ umożliwiają kolorowanie różnych języków programowania. Możemy nadać nazwę języka programowania używając auto-uzupełnienia, kod został pokolorowany używając konkretnych ustawień kolorowania składni:

```javascript
document.write('Hello World');
```

Możesz zaznaczyć również już wklejony kod w edytorze, i użyć komendy  by zamienić go w kod. Użyj kombinacji Ctrl+`, by dodać fragment kodu bez oznaczników języka.

Tabelki

Dodaj przykładową tabelkę używając komendy . Przykładowa tabelka składa się z dwóch kolumn, nagłówka i jednego wiersza.

Wygeneruj tabelkę na podstawie szablonu. Oddziel komórki separatorem ; lub |, a następnie zaznacz szablonu.

nazwisko;dziedzina;odkrycie
Pitagoras;mathematics;Pythagorean Theorem
Albert Einstein;physics;General Relativity
Marie Curie, Pierre Curie;chemistry;Radium, Polonium

Użyj komendy by zamienić zaznaczony szablon na tabelkę Markdown.

Lista uporządkowana i nieuporządkowana

Możliwe jest tworzenie listy numerowanych oraz wypunktowanych. Wystarczy, że pierwszym znakiem linii będzie * lub - dla listy nieuporządkowanej oraz 1. dla listy uporządkowanej.

Użyj komendy by dodać listę uporządkowaną.

1. Lista numerowana
2. Lista numerowana

Użyj komendy by dodać listę nieuporządkowaną.

* Lista wypunktowana
* Lista wypunktowana
** Lista wypunktowana (drugi poziom)

Składnia Markdown

Edytor obsługuje składnię Markdown, która składa się ze znaków specjalnych. Dostępne komendy, jak formatowanie , dodanie tabelki lub fragmentu kodu są w pewnym sensie świadome otaczającej jej składni, i postarają się unikać uszkodzenia jej.

Dla przykładu, używając tylko dostępnych komend, nie możemy dodać formatowania pogrubienia do kodu wielolinijkowego, albo dodać listy do tabelki - mogłoby to doprowadzić do uszkodzenia składni.

W pewnych odosobnionych przypadkach brak nowej linii przed elementami markdown również mógłby uszkodzić składnie, dlatego edytor dodaje brakujące nowe linie. Dla przykładu, dodanie formatowania pochylenia zaraz po tabelce, mogłoby zostać błędne zinterpretowane, więc edytor doda oddzielającą nową linię pomiędzy tabelką, a pochyleniem.

Skróty klawiszowe

Skróty formatujące, kiedy w edytorze znajduje się pojedynczy kursor, wstawiają sformatowany tekst przykładowy. Jeśli w edytorze znajduje się zaznaczenie (słowo, linijka, paragraf), wtedy zaznaczenie zostaje sformatowane.

  • Ctrl+B - dodaj pogrubienie lub pogrub zaznaczenie
  • Ctrl+I - dodaj pochylenie lub pochyl zaznaczenie
  • Ctrl+U - dodaj podkreślenie lub podkreśl zaznaczenie
  • Ctrl+S - dodaj przekreślenie lub przekreśl zaznaczenie

Notacja Klawiszy

  • Alt+K - dodaj notację klawiszy

Fragment kodu bez oznacznika

  • Alt+C - dodaj pusty fragment kodu

Skróty operujące na kodzie i linijkach:

  • Alt+L - zaznaczenie całej linii
  • Alt+, Alt+ - przeniesienie linijki w której znajduje się kursor w górę/dół.
  • Tab/⌘+] - dodaj wcięcie (wcięcie w prawo)
  • Shit+Tab/⌘+[ - usunięcie wcięcia (wycięcie w lewo)

Dodawanie postów:

  • Ctrl+Enter - dodaj post
  • ⌘+Enter - dodaj post (MacOS)