Kapitel 6: Arithmetik in JavaCard Problem: Keine Integers in

Kapitel 6: Arithmetik in JavaCard
Problem: Keine Integers in JavaCard
ToDo: Rechnen mit Bytes und Shorts
Java SmartCards, Kap. 6 (1/20)
Hex-Notation
1 Byte = 8 Bit, b7 b6 b5 b4 b3 b2 b1 b0
0101
| {z }
| {z } 1110
= 0 ∗ 27 + 1 ∗ 26 + 0 ∗ 25 + 1 ∗ 24 +
1 ∗ 23 + 1 ∗ 22 + 1 ∗ 21 + 0 ∗ 20 = 94
5
E
= 0x5E = 5 ∗ 16 + 14 = 94
Hex: 0. . . 9, 10 = A, 11 = B, 12 = C, 13 = D, 14 = E, 15 = F
Java SmartCards, Kap. 6 (2/20)
Wertebereiche in Java
Typ
Länge
Minimaler Wert
byte
8 Bit
-128
short
16 Bit
-32768
int
32 Bit
-2147483648
long
64 Bit
-9223372036854775808
Maximaler Wert
127
32767
2147483647
9223372036854775807
Java SmartCards, Kap. 6 (3/20)
Arithmetik in Java:
Java Language Specification 4.2.2 (Integer Operations):
If an integer other than a shift operator has at least one operand of type long, then the operation is carried out using
64-bit precision, and the result of the numerical operator is of
type long. If the other operand is not long, it is first widened
(§5.1.4) to type long by numeric promotion (§5.6). Otherwise, the operation is carried out using 32-bit precision, and the
result of the numerical operator is of type int. If either operand is not an int, it is first widened to type int by numeric
promotion.
Java SmartCards, Kap. 6 (4/20)
Arithmetik in Java:
•
Argumente werden automatisch nach int konvertiert
•
Berechnung mit Integers
•
Ergebnis ist int
•
Kein Check auf Over-/Underflow
short x, y; . . . short z = (short)(x * y); (Cast notwendig)
1.000.000 ∗ 1.000.000 = −727.379.968 (Overflow)
(Bem.: Ein Argument long: Berechnung/Ergebnis long,
analog für float, double)
Java SmartCards, Kap. 6 (5/20)
Arithmetik in Java:
•
Automatische Konvertierung byte → short → int
•
Umgekehrt ist expliziter Cast notwendig!
•
•
Cast: überzählige“ Bits abschneiden
”
Ergebnis von Arithmetikoperationen ist immer vom Typ int.
•
Arithmetikoperationen: +, -, *, /, % und
•
Bitoperationen: & (And), | (Or), ^ (Xor), ~ (Komplement)
links-shift <<, rechts-shift >> (mit Vorzeichen), >>> (mit Nullen)
•
Negative Zahlen: 2er-Komplement
Java SmartCards, Kap. 6 (6/20)
Arithmetik in Java:
Java Language Specification 5.1.2 (Widening Primitive Conversion):
A widening conversion of a signed integer value to an integral
type T simply sign-extends the two’s-complement representation of the integer value to fill the wider format.
Java Language Specification 5.1.3 (Narrowing Primitive Conversion):
A narrowing conversion of a signed integer to an integral type
T simply discards all but the n lowest bits, where n is the
number of bits used to represent type T. In addition to a possible loss of information about the magnitude of the numeric
value, this may cause the sign of the resulting value to differ
from the sign of the input value.
Java SmartCards, Kap. 6 (7/20)
2er-Komplement:
1. Schritt:
bilde Bitdarstellung des Betrags
34 ⇒ 0010 0010
2. Schritt:
bitweise Invertierung
⇒ 1101 1101
3. Schritt:
addiere 1
⇒ 1101 1110 = -34
0010 0010
+34
=
0000 0000 0010 0010
0000 0000 0000 0000 0000 0000 0010 0010
1101 1110
-34
=
1111 1111 1101 1110
1111 1111 1111 1111 1111 1111 1101 1110
(byte)
(short)
(int)
(byte)
(short)
(int)
Java SmartCards, Kap. 6 (8/20)
Eigenschaften
•
Führendes Bit ist Vorzeichen: 0 =
ˆ positive, 1 =
ˆ negative Zahl
•
⇒ größte Byte-Zahl: 0111 1111 = 0x7F = 127
•
⇒ kleinste Byte-Zahl: 1000 0000 = 0x80 = -128
•
Cast schneidet obere Bits ab: 0000 1000 1111 1111 ⇒ 1111 1111
•
Rest: 5 % 3 = 2, -5 % 3 = -2, 5 % -3 = 2, -5 % -3 = -2
•
int i;
0 ≤ i ∧ i % 256 ≤ 127
→ (byte)i = i % 256
0 ≤ i ∧ 127 < i % 256
→ (byte)i = (i % 256) − 256
i < 0 ∧ i % 256 < −128 → (byte)i = (i % 256) + 256
i < 0 ∧ − 128 ≤ i % 256 → (byte)i = i % 256
Java SmartCards, Kap. 6 (9/20)
6 weitere Bemerkungen dazu:
1. Arithmetik ist vom Typ int:
byte b = (byte)(x + y);
(x, y Bytes)
byte b = (byte)(x & 0x7F);
(x Byte)
•
Beide Argumente werden in Integers umgewandelt
•
die Rechenoperation wird auf Integers ausgeführt
•
das Ergebnis ist ein Integer
⇒ Cast notwendig. (Auch wenn Ergebnis in ein Byte passt.)
2. Integer Literale:
•
Konstanten sind immer vom Typ Integer
byte b = 0x20; (narrowing primitive conversion)
byte b = (byte)0xA0; (kein signed Byte)
f((short)0) (bei Methoden keine narrowing primitive conversion)
Java SmartCards, Kap. 6 (10/20)
3. Casts: A0 = 1010 0000 - führendes 1-Bit
byte → int: A0 → FF FF FF A0
int → byte: 00 00 00 A0 → A0
4. Signed vs. Unsigned Bytes:
(int)0xA0 = 160, aber (int)(byte)0xA0 = –96.
unsigned byte → int: (b & 0xFF)
da (int)((byte)0xA0 & 0xFF) = 160
5. int → High-Byte, Low-Byte:
(i >> 8) & 0xFF und i & 0xFF (vgl. setShort)
High-Byte, Low-Byte → int:
(b1 << 8) | (b2 & 0xFF) (vgl. getShort)
6. (short)(-1 >>> 15) == -1
Java SmartCards, Kap. 6 (11/20)
Short- vs. Integer-Arithmetik
1. Beispiel: short x1 = 20000, x2 = (short)((x1 * 5) / 10);
Integer-Arithmetik: x2 = 10000
Short-Arithmetik:
x2 = –3107
2. Beispiel: short x1 = 20000, x2 = 30000,
x3 = (short)((x1 + x2) - x2);
Integer-Arithmetik: x3 = 20000
Short-Arithmetik:
x3 = 20000
3. Beispiel: short x1 = 20000, x2 = 30000;
boolean res = (x1 < x1 + x2);
Integer-Arithmetik: res = true;
Short-Arithmetik:
res = false;
Java SmartCards, Kap. 6 (12/20)
Der cap-Converter:
•
prüft, dass kein int, long, . . . benutzt wird.
•
prüft, dass short-Arithmetik = int-Arithmetik
⇒ Rechengesetze
Beispiele:
1.
(short)((x * y) - z)
Ok
2.
x + y < z
Fehler!
3.
(x + y) / 1000
Fehler!
Java SmartCards, Kap. 6 (13/20)
Prinzip
short-Arithmetik = int-Arithmetik, wenn . . .
1. das Ergebnis einer Operation (sofort) nach (short) oder (byte)
gecastet wird:
(short)(x ⊕ y)
2. die Operation innerhalb eines Casts stattfindet und bestimmte Rechenregeln gelten:
(short)(a ⊕1 ((b ⊕2 c) ⊕3 d))
3. das Ergebnis von der Größe her in ein short passt:
byte b, c; ⇒ −32768 < b * (x % c) < 32767
Java SmartCards, Kap. 6 (14/20)
Rechengesetze (1):
s, t: bel. Ausdrücke mit Ergebnistype int, z. B. s = (x * y) * z
1.
Unäres Minus:
(short)(- s)
2.
Addition:
(short)(s + t) = (short)((short)s + t)
3.
Subtraktion:
(short)(s - t) = (short)(s - (short)t)
4.
Multiplikation:
(short)(s * t) = (short)((short)s * t)
= (short)(- (short)s)
und sämtliche Varianten.
Bem.: 1. wird vom cap converter nicht akzeptiert.
Java SmartCards, Kap. 6 (15/20)
Rechengesetze (2):
1.
Komplement:
2.
Bitweises Und:
(short)(~s)
(short)(s & t)
= (short)(~(short)s)
= (short)((short)s & t)
3.
Bitweises Oder:
(short)(s | t)
= (short)((short)s | t)
4.
Bitweises Xor:
(short)(s ^ t)
= (short)((short)s ^ t)
5.
Links-Shift:
(short)(s << n) = (short)((short)s << n)
und sämtliche Varianten.
Java SmartCards, Kap. 6 (16/20)
Rechengesetze (3):
Im Allgemeinen (auch für Varianten):
1. (short)(s / t) 6= (short)((short)s / (short)t)
Beispiel: s = 216 , t = 215
2. (short)(s % t) 6= (short)((short)s % (short)t)
Beispiel: s = 2 ∗ 216 − 1, t = 216 − 1
3. (short)(s >> n) 6= (short)((short)s >> n)
Beispiel: s = 215 , n = 1
4. (short)(s >>> n) 6= (short)((short)s >>> n)
Beispiel: s = 215 , n = 1
gilt natürlich, wenn s und t in ein short passen.
Java SmartCards, Kap. 6 (17/20)
Rechengesetze (4):
Im Allgemeinen (auch für Varianten):
1. s < t 6⇔ (short)s < (short)t
2. (short)s == (short)t 6⇒ s == t
aber natürlich s == t ⇒ (short)s == (short)t
⇒ (short)(x + y) == z Cast ist notwendig!
gilt natürlich, wenn s und t in ein short passen.
Java SmartCards, Kap. 6 (18/20)
Rechengesetze (5):
. . . gilt, wenn s und t in ein short passen?
1. short x,y,z ⇒ x & y “passt” – Ok!
⇒ (x & y) == z kein Cast notwendig.
Ebenso für |, ^ , ~, >>, >>>
2. short x,y,z ⇒ x % y “passt” – Ok!
⇒ (x % y) == z kein Cast notwendig.
Ebenso für /
3. byte x,y ⇒ x + y, x + 127 “passt” – Ok!
⇒ (x + y) == z kein Cast notwendig.
Ebenso für -, *
4. byte x,y,z ⇒ x + y + z, x + 128 “passt” – Fehler!
Java SmartCards, Kap. 6 (19/20)
Spezielle Konstrukte:
1. Bei Compound assignment impliziter cast:
short x;
x += y + z; ok, ≡ x = (short)(x + (y + z))
x /= y + z; nicht ok, ≡ x = (short)(x / (y + z))
2. Bei Shift wird 2. Argument n implizit zu (n & 31):
x >> n ≡ x >> (n & 31)
Java SmartCards, Kap. 6 (20/20)