Class FlickerCode

java.lang.Object
org.kapott.hbci.manager.FlickerCode

public class FlickerCode extends Object
Implementierung des Flicker-Codes fuer optisches ChipTAN. Basiert auf der Javascript-Implementierung von http://6xq.net/media/00/20/flickercode.html Die Javascript-Implementierung war jedoch nicht mehr aktuell (basiert auf HHD 1.3).
  • Field Details

    • LC_LENGTH_HHD14

      private static final int LC_LENGTH_HHD14
      Die Anzahl der Bytes, in der die Laenge des Challenge bei HHD 1.4 steht. Bei HHD 1.3 war das noch 2 Zeichen lang. Wenn der Flicker-Code nicht in "Challenge HHDuc" uebertragen wurde sondern direkt im Freitext-Challenge, koennen wir das Problem umgehen, indem wir in clean() einfach eine "0" vorn anhaengen. Wenn er aber tatsaechlich im "Challenge HHDuc" steht, kann man dem Code nicht ansehen, ob es ein HHD 1.3-Code ist. In dem Fall hilft nur Tryinvalid input: '&Error'. Also mit HHD 1.4 parsen. Und wenn das fehlschlaegt, dann HHD 1.3 versuchen.
      See Also:
    • LC_LENGTH_HHD13

      private static final int LC_LENGTH_HHD13
      Die Anzahl der Bytes, in der die Laenge des Challenge bei HHD 1.3 steht.
      See Also:
    • LDE_LENGTH_DEFAULT

      private static final int LDE_LENGTH_DEFAULT
      Default-Laenge der LDE-Laengen-Angabe.
      See Also:
    • LDE_LENGTH_SPARDA

      private static final int LDE_LENGTH_SPARDA
      Fallback-Laenge der LDE-Laengen-Angabe bei der Sparda.
      See Also:
    • BIT_ENCODING

      private static final int BIT_ENCODING
      Die Position des Bits, welches das Encoding enthaelt.
      See Also:
    • BIT_CONTROLBYTE

      private static final int BIT_CONTROLBYTE
      Die Position des Bits, welches festlegt, ob ein Controlbyte folgt.
      See Also:
    • version

      public FlickerCode.HHDVersion version
      Die HHD-Version.
    • lc

      public int lc
      Laenge des gesamten Codes.
    • startCode

      public FlickerCode.Startcode startCode
      Der Startcode.
    • de1

      public FlickerCode.DE de1
      Datenelement 1.
    • de2

      public FlickerCode.DE de2
      Datenelement 2.
    • de3

      public FlickerCode.DE de3
      Datenelement 3.
    • rest

      public String rest
      Der Rest des Codes. Mit dem koennen wir nichts anfangen
  • Constructor Details

    • FlickerCode

      public FlickerCode()
      ct. Parameterloser Konstruktor zum manuellen Zusammenstecken eines Codes.
    • FlickerCode

      public FlickerCode(String code)
      ct. Parst den HHDuc-Code aus dem uebergebenen Code.
      Parameters:
      code - der zu parsende Code.
    • FlickerCode

      public FlickerCode(HHDVersion hhd, String code)
      ct. Parst den HHDuc-Code aus dem uebergebenen Code.
      Parameters:
      hhd - die HHD-Version. Kann NULL sein.
      code - der zu parsende Code.
  • Method Details

    • tryParse

      public static FlickerCode tryParse(String challenge, String hhduc)
      Versucht, aus Challenge und Challenge HHDuc den Flicker-Code zu extrahieren und ihn in einen flickerfaehigen Code umzuwandeln. Nur wenn tatsaechlich ein gueltiger Code enthalten ist, der als HHDuc-Code geparst und in einen Flicker-Code umgewandelt werden konnte, liefert die Funktion den Code. Sonst immer NULL.
      Parameters:
      challenge - der Challenge-Text. Das DE "Challenge HHDuc" gibt es erst seit HITAN4. Einige Banken haben aber schon vorher optisches chipTAN gemacht. Die haben das HHDuc dann direkt im Freitext des Challenge mitgeschickt (mit String-Tokens zum Extrahieren markiert). Die werden vom FlickerCode-Parser auch unterstuetzt.
      hhduc - das echte Challenge HHDuc.
      Returns:
      der geparste Flickercode oder NULL.
    • tryParse

      public static FlickerCode tryParse(HHDVersion hhd, String challenge, String hhduc)
      Versucht, aus Challenge und Challenge HHDuc den Flicker-Code zu extrahieren und ihn in einen flickerfaehigen Code umzuwandeln. Nur wenn tatsaechlich ein gueltiger Code enthalten ist, der als HHDuc-Code geparst und in einen Flicker-Code umgewandelt werden konnte, liefert die Funktion den Code. Sonst immer NULL.
      Parameters:
      hhd - die HHD-Version. Kann NULL sein.
      challenge - der Challenge-Text. Das DE "Challenge HHDuc" gibt es erst seit HITAN4. Einige Banken haben aber schon vorher optisches chipTAN gemacht. Die haben das HHDuc dann direkt im Freitext des Challenge mitgeschickt (mit String-Tokens zum Extrahieren markiert). Die werden vom FlickerCode-Parser auch unterstuetzt.
      hhduc - das echte Challenge HHDuc.
      Returns:
      der geparste Flickercode oder NULL.
    • parse

      private void parse(String code, FlickerCode.HHDVersion version)
      Parst den Code mit der angegebenen HHD-Version.
      Parameters:
      code - der zu parsende Code.
      version - die HHD-Version.
    • parse

      private void parse(String code, FlickerCode.HHDVersion version, int ldeLen)
      Parst den Code mit der angegebenen HHD-Version.
      Parameters:
      code - der zu parsende Code.
      version - die HHD-Version.
      ldeLen - explizite Angabe der Laenge des LDE.
    • clean

      private String clean(String code)
      Entfernt das CHLGUC0026....CHLGTEXT aus dem Code, falls vorhanden. Das sind HHD 1.3-Codes, die nicht im "Challenge HHDuc" uebertragen wurden sondern direkt im Challenge-Freitext,
      Parameters:
      code -
      Returns:
    • render

      public String render()
      Rendert den flickerfaehigen Code aus dem Challenge im HHD-Format.
      Returns:
      der neu generierte Flicker-Code.
    • createPayload

      private String createPayload()
      Generiert den Payload neu. Das ist der komplette Code, jedoch ohne Pruefziffern am Ende.
      Returns:
      der neu generierte Payload.
    • createXORChecksum

      private String createXORChecksum(String payload)
      Berechnet die XOR-Checksumme fuer den Code neu.
      Parameters:
      der - Payload.
      Returns:
      die XOR-Checksumme im Hex-Format.
    • createLuhnChecksum

      private String createLuhnChecksum()
      Berechnet die Luhn-Pruefziffer neu.
      Returns:
      die Pruefziffer im Hex-Format.
    • toString

      public String toString()
      Overrides:
      toString in class Object
      See Also:
    • reset

      private void reset()
      Resettet den Code.
    • equals

      public boolean equals(Object obj)
      Overrides:
      equals in class Object
      See Also:
    • toHex

      private static String toHex(int n, int len)
      Wandelt die Zahl in Hex-Schreibweise um und fuellt links mit Nullen auf, bis die Laenge "len" erreicht ist.
      Parameters:
      n - die Zahl.
      len - die zu erreichende Laenge.
      Returns:
      die links mit Nullen aufgefuellte Zahl in HEX-Schreibweise.
    • toHex

      private static String toHex(String s)
      Wandelt alle Zeichen des String gemaess des jeweiligen ASCII-Wertes in HEX-Codierung um. Beispiel: Das Zeichen "0" hat den ASCII-Wert "30" in Hexadezimal-Schreibweise.
      Parameters:
      s - der umzuwandelnde String.
      Returns:
      der codierte String.
    • quersumme

      private static int quersumme(int n)
      Berechnet die Quersumme.
      Parameters:
      n - die Zahl, deren Quersumme errechnet werden soll.
      Returns:
      die Quersumme.
    • getBitSum

      private static int getBitSum(int num, int bits)
      Liefert die Summe der Bit-Wertigkeiten fuer die genannten Bits (beginndend bei 0 und beim kleinsten Bit, angegebens inclusive). Beispiel: num = 156 (-> 10011100) bits = 5 Es wird die Summe der Bitwertigkeiten 2^0 bis 2^5 errechnet. Also der Wert von **011100 = 2^4+2^3+s^2 = 28
      Parameters:
      num - Zahl, aus der die Summe berechnet werden soll.
      bits - Anzahl der Bits (beginnend bei 0 und beim kleinsten Bit, angegebenes inclusive), deren Wertigkeit addiert werden soll.
      Returns:
      der errechnete Wert.
    • isBitSet

      private static boolean isBitSet(int num, int bit)
      Prueft, ob in der genannten Zahl das angegebene Bit gesetzt ist.
      Parameters:
      num - die zu pruefende Zahl.
      bit - die Nummer des zu pruefenden Bits. Wobei "0" das kleinste (rechts) und "7" das groesste (links) Bit ist.
      Returns:
      true, wenn das Bit gesetzt ist.