Kodowanie i wykrywanie błędów za pomoca algorytmu Hamminga

0

Cześć,

Z pomocą internetów stworzyłem sobie program, który ma za zadanie zmienić wprowadzony tekst z klawiatury na ciąg znaków binarnych, dodać do niego crc, a na końcu zakodować wszystko hammingiem. Tą część mam już z głowy. Udało się również zrobić zakłócanie konkretnych pozycji, ich korekcja a także odkodowywanie. Jednak przy testowaniu aplikacji pojawia się jeden błąd i to w określonym przypadku. Dotyczy on zakłócenia pierwszej i ostatniej pozycji w ciągu ( bit hamminga oraz bit parzystości). Zdaje sobie sprawę ,że ten algorytm nie jest przystosowany do korekcji 2 błędów, ale w tym wypadku powinien odkodować blok danych ponieważ nie został on zakłócony. Wszystkie inne możliwe opcje działają czyli:

  • detekcja i korekcja zakłócenia jednego bitu,
  • detekcja i częściowa korekcja przy zakłóceniu dwóch lub więcej bitów w ciągu.

Tutaj wstawiam kod błędu

Exception in thread "AWT-EventQueue-0" java.lang.ArrayIndexOutOfBoundsException: 216
	at teleinforma.Teleinforma.Odkodowanie(Teleinforma.java:198)
	at teleinforma.Teleinforma.jButton2ActionPerformed(Teleinforma.java:552)
	at teleinforma.Teleinforma.access$100(Teleinforma.java:22)
	at teleinforma.Teleinforma$2.actionPerformed(Teleinforma.java:355)
	at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:2022)
	at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2346)
	at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:402)
	at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:259)
	at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:252)
	at java.awt.Component.processMouseEvent(Component.java:6525)
	at javax.swing.JComponent.processMouseEvent(JComponent.java:3324)
	at java.awt.Component.processEvent(Component.java:6290)
	at java.awt.Container.processEvent(Container.java:2234)
	at java.awt.Component.dispatchEventImpl(Component.java:4881)
	at java.awt.Container.dispatchEventImpl(Container.java:2292)
	at java.awt.Component.dispatchEvent(Component.java:4703)
	at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4898)
	at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4533)
	at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4462)
	at java.awt.Container.dispatchEventImpl(Container.java:2278)
	at java.awt.Window.dispatchEventImpl(Window.java:2750)
	at java.awt.Component.dispatchEvent(Component.java:4703)
	at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:758)
	at java.awt.EventQueue.access$500(EventQueue.java:97)
	at java.awt.EventQueue$3.run(EventQueue.java:709)
	at java.awt.EventQueue$3.run(EventQueue.java:703)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:75)
	at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:86)
	at java.awt.EventQueue$4.run(EventQueue.java:731)
	at java.awt.EventQueue$4.run(EventQueue.java:729)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:75)
	at java.awt.EventQueue.dispatchEvent(EventQueue.java:728)
	at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:201)
	at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)
	at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105)
	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)
	at java.awt.EventDispatchThread.run(EventDispatchThread.java:82)

Trochę to dziwne bo przykładowo wstawiam 555555555 ( dziewięć piątek) i program zadziała, a wstawiajać już 5555555555 ( dziesięć piątek) jest już błąd.

Ma ktoś pomysł co to może oznaczać i jak ten błąd naprawić ?

Poniżej kod metody odkodowywania w której myślę, że siedzi błąd

 public void Odkodowanie(int tabA[], int parity_count) 
    {	
               int power;
	
        int parity[] = new int[parity_count];
		
        String syndrome = new String();
	
        for (power = 0; power < parity_count; power++) {

            for (int i = 0; i < tabA.length; i++) {
				
                int k = i + 1;
                String s = Integer.toBinaryString(k);
                int bit = ((Integer.parseInt(s)) / ((int) Math.pow(10, power))) % 10;
                if (bit == 1) {
                    if (tabA[i] == 1) {
                        parity[power] = (parity[power] + 1) % 2;
                    }
                }
            }
            syndrome = parity[power] + syndrome;
        }
		
        int error_location = Integer.parseInt(syndrome, 2);
         String asdd= "";
        if (error_location != 0) {
            
                jLabel15.setText("błędny bit " + error_location);
!!!!!!! -->> lnia 198       tabA[error_location - 1] = (tabA[error_location - 1] + 1) % 2;
            
           
            for (int i = 0; i < tabA.length; i++) {
                                
                asdd+= Integer.toString(tabA[tabA.length - i - 1]);
                jLabel12.setText(asdd);
            }
            
        } else {
            
            jLabel15.setText("brak błedu");
            for (int i = 0; i < tabA.length; i++) {
                             
                asdd+= Integer.toString(tabA[tabA.length - i - 1]);
                jLabel12.setText(asdd);
            }
        }

       
        power = parity_count - 1;
        
         int k=0;
         wynik = new int[dlogoscJ3];
        for (int i = tabA.length; i > 0; i--) {
            if (Math.pow(2, power) != i) {
               //System.out.print(a[i - 1]);
               wynik[k]=tabA[i-1];
               k++;
                
            } else {
                power--;
            }
        }
        
        for (int i=0; i< wynik.length; i++){
        
        }
        int s = 0;
        int kk =0;
        String obcietyWynik = "";
        int dl =wynik.length-dlogoscJ2;
        int dl2 = dl+8;
        int licznik = dlogoscJ2/8;
       // crcPo = new byte[dlogoscJ1*2];
        String ascii;
        int temp = 0;
        int zz = 0;
        String[] asciiTemp = new String[licznik];
        for(int p = licznik; p>0; p--){
            
            for(int j = dl ; j<dl2; j++, kk++){
                
               // System.out.print(wynik[j]);
               // System.out.println("\nwynik " +wynik[j]);
               if(wynik[j]==1)
                   s+=Math.pow(2,kk);
            }
            ascii = Integer.toString(s);
           
            asciiTemp[temp] = ascii;
            temp++;
            s = 0;
            kk=0;
            dl += 8;
            dl2 = dl+8;
           // System.out.println("trrr " + s);
        }
        for(int l = asciiTemp.length-1; l>=0; l--){
           // obcietyWynik+=asciiTemp[l];
            obcietyWynik+=Character.toString((char)Integer.parseInt(asciiTemp[l]));
        }
        asciiPo= obcietyWynik.getBytes();
        System.out.println("crcPo " + new String(asciiPo));
     
        
        System.out.println("ascii " + s);
    }
0

Wypadałoby zaznaczyć wiersz 198. Przekraczasz zakres tablicy, zapewne masz tablicę 216-elemetową i odwołujesz się do elementu o indeksie 216.

0

Linia 198 jest już zaznaczona.

0

Jaki rozmiar ma tablica tabA, jaka jest wartość zmiennej error_location? Użyj debuggera lub zastosuj "dupa debugging"

System.out.println(tabA.length+"  "+syndrome+" "+error_location);
0
bogdans napisał(a):

zastosuj "dupa debugging"

Taka krotka anegdotka na boku: od paru lat pracuje w Niemczech, w tym czasie jestem w 3 firmie, 5 zespole. W kazdym zespole w ktorym pracowalem Niemcy i reszta wiedza co to 'dupa' i 'dupa debugging', i sami tego uzywaja. Ostatnio mialem niezla polewke jak pomagalem koledze poprawiac jakiegos buga, i w jego wypocinach widzialem dumne Log.e("DUPA!", ...) ;d

0

Skorzystałem z tego :

 System.out.println(tabA.length+"  "+syndrome+" "+error_location); 

Przy wpisanych 10 piątkach i nie wprowadzeniu błędu :

  • długości tablic przed 198 :102 0000001 1
  • długości tablic po 198 :102 0000000 0
    Przy wpisanych 10 piątkach i wprowadzeniu błędu na pierwszym bicie :
  • długości tablic przed 198 :102 0000001 1
  • długości tablic po 198:102 0000001 1
    Przy zakłóconych 1 i ostatnim bicie standardowo błąd
    *Dlugość tablic przed 198: 102 1100111 103

Przy wpisanych 9 piątkach i nie wprowadzeniu błędu :

  • Dlugość tablic przed 198: 95 0000000 0
  • długości tablic po 198 :95 0000000 0
    Przy wpisanych 10 piątkach i wprowadzeniu błędu na pierwszym bicie :
  • długości tablic przed 198 :95 0000001 1
  • długości tablic po 198:95 0000001 1
    Przy zakłóconych 1 i ostatnim bicie tutaj nie ma błędu i długości są następujące
  • długości tablic przed :95 1011110 94
  • długości tablic po 198 :95 1011110 94
0

Wstaw wiersz

System.out.println(tabA.length+"  "+syndrome+" "+error_location);

przed wierszem 198. Wstawiłeś po i nadal nic nie wiesz.

0

Wstawiłem również przed i edytowałem poprzedni post, wyniki sa takie same z tą różnicą, że można odczytać długości tablicy przed błędem czyli "Długość tablic przed 198: 102 1100111 103"

0

Średnim rozwiązaniem tego problemu jest zrobienie bloku try, catch(czyli ustawienie na sztywno wartości wynikowych w razie błędu) bo ten błąd pojawia się tylko w przypadku zakłócania 1 i ostatniego bitu, wszystkie inne kombinacje działają. Jeśli kogoś zaciekawił dany problem, mogę udostępnić inne fragmenty kodu lub całą aplikacje.

1 użytkowników online, w tym zalogowanych: 0, gości: 1