Autor |
Beitrag |
Killi
      
Beiträge: 299
Win*
D6 Prof
|
Verfasst: Fr 24.10.03 15:12
Hi!
Es geht um folgendes problem: Ich lese eine Krankenkassenkarte mit TSmartCard aus, Beispiel-Code war dabei, damit kann ich nix anfangen, habe es eben drin gelassen - Daten werden auch wunderbar gelesen, allerdings gibt es auch Karten auf denen der Name mit Umlauten, also ä,ö und üs geschrieben wird - hier bekomme ich nur ein "{"...wie kann ich das verhindern? Liegt es etwa daran (?):
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75:
| procedure TFKarte.ExecSCardCmd(Cmd,DataIn: String); const BufferSize = 32768; var P,pDataIn: PChar; DataASCII, DataHex, DataInHex: String; C: Integer; Len, LenIn: LongInt; begin MemoDataOut.Clear; if (Cmd = '') then begin MemoDataOut.Lines.Add('no command'); exit; end; with EditDataIn do if ((Font.Color=clRed) and (Text='(nil)')) then DataIn:=''; ShowCommand(Cmd,DataIn); P:=AllocMem(BufferSize); if DataIn='' then begin pDataIn:=nil; LenIn:=0; end else begin if RadioButtonHEX.Checked then begin DataInHex:=HexStrToTxt(DataIn); EditDataIn.Text := TxtToHexStr(DataInHex); LenIn := Length(DataInHex); pDataIn:=@DataInHex[1]; end else begin LenIn := Length(DataIn); pDataIn:=@DataIn[1]; end; end;
try
Len:=SmartCard.Comand(Cmd,pDataIn,LenIn,P,BufferSize);
if Len <> 0 then begin
DataASCII:=''; for C:=0 to Len-1 do begin case P[C] of #0..#31: DataASCII:=DataASCII+'°'; else DataASCII:=DataASCII+P[C]; end; end; if DataASCII <> '' then begin MemoDataOut.Lines.Add(DataASCII); end; end; except on E:ESmartCard do begin MemoDataOut.Lines.Add(' '); MemoDataOut.Lines.Add('SmartcardException: '+E.Message); end; on E:Exception do begin MemoDataOut.Lines.Add(' '); MemoDataOut.Lines.Add('Exception: '+E.Message); end; end; FreeMem(P,BufferSize); end; |
Hoffe ihr könnt mir helfen....
|
|
Wolff68
      
Beiträge: 302
Erhaltene Danke: 1
WinXP home
D6 Prof
|
Verfasst: Fr 24.10.03 18:35
Generell könnte es an der verwendeten Schriftart liegen, da ASCII-Codes über 128 nicht "genormt" sind.
Ebenso kann es sein, daß aus Speicherplatzgründen die Zeichen auf der Karte in nur 4 Bits gespeichert werden (Also nur ASCII 0-128 zulässt)
So könnte zB aus einem ü eine { werden... (oder hab ich mich jetzt verrechnet?)
Du könntest aber mal nachsehen, welche ASCII-Codes Du von der Karte überhaupt bekommst.
Ä= 196
Ö= 214
Ü= 220
ä= 228
ö= 246
ü= 252
ß= 223
{= 123
_________________ "Der Mensch ist nicht was er sich vorstellt oder wünscht zu sein, sondern das was andere in ihm sehen."
|
|
Luckie
Ehemaliges Mitglied
Erhaltene Danke: 1
|
Verfasst: Fr 24.10.03 19:22
Ich glaube nicht, dass die Zeichen nur mit 4 Bits codiert sind. Wie willst du sonst Müller von Mueller unterscheiden? Soll es nämlich auch geben.
|
|
Killi 
      
Beiträge: 299
Win*
D6 Prof
|
Verfasst: Mi 29.10.03 10:06
Hi!
Die Theorie von Wolff68 könnte stimmen, da ich die Umlaute etc. schon als ~ zurückbekomme - und meine LÖSUNG für das Problem stimmt auch, ich ersetzte #225 durch ß, dann kommt die Straße richtig - allerdings werden ja äs, ös und üs auch mit einem ~ gekennzeichnet - und hie ist mein Problem, es kommen anscheinend keine Datensätze über #128 an...d.h. ich bekomme immer nur ein ~ schon im ASCII-Code.....
Kann das am Treiber liegen??? Weil das kartenlesegerät müsste es können...von der Firma gibts auch eine Krankenkassenlösung die das kann....ich versteh gar nix mehr!
|
|
Maggi
      
Beiträge: 160
WIN XP, WIN 2003
D5 Enter D 2006
|
Verfasst: Mi 29.10.03 14:11
Hi,
kann es sein das du ineinem ganz anderen Zeichensatz unterwegs bist.
OEM oder so, dann mußt du erst konvertieren und alles wird gut. Wird auch in der Hilfe sehr gut beschrieben!
Gruß
Maggi
_________________ "Wir haben den Kontakt zur Realität verloren, aber die findet uns schon wieder"
|
|
Killi 
      
Beiträge: 299
Win*
D6 Prof
|
Verfasst: Mi 29.10.03 14:37
OEM Zeichensatz sagt mir leider nix, hab keine Ahnung wie die Daten codiert sind - guck dir oben mal meinen Code an, is rauskopiert - das macht den ganzen sch...! Aber da steht nur was von ASCII zu norml. Text!?
Also...!!??
|
|
Killi 
      
Beiträge: 299
Win*
D6 Prof
|
Verfasst: Do 30.10.03 12:01
kann mir keiner mehr helfen? 
|
|
Spieler1
      
Beiträge: 469
D6 Pers
|
Verfasst: Do 30.10.03 23:57
Das geht schon, du musst nur ein unsigned char verwenden, da sind dann auch solche Sonderzeichen drin.
|
|
Killi 
      
Beiträge: 299
Win*
D6 Prof
|
Verfasst: Fr 31.10.03 10:13
unsigned??? Wie mach ich das? Kann ja fast nix mit der Prozedur anfangen...kannst du mir helfen?
|
|
Ja-Pa
      
Beiträge: 458
Win XP, Suse 9.3
D1, D3, D5 Std, D7 Pro, D2005 Pers, Kylix 3
|
Verfasst: Fr 31.10.03 13:46
Maggi hat folgendes geschrieben: |
OEM oder so, dann mußt du erst konvertieren und alles wird gut. |
Dieses Problem habe ich auch, wenn ich ActiveX-Controls einen String übergeben will.
Der hängt sich bei Sonderzeichen dann auf.
Vielleicht muss ich das auch konvertieren?
Wie mache ich das?
Gruß, Ja-Pa
_________________ Der Autor dieses Textes haftet nicht für Schäden an Soft- oder Hardware
oder Vermögensschäden, die durch das Benutzen des Textes entstehen.
|
|
Spieler1
      
Beiträge: 469
D6 Pers
|
Verfasst: Fr 31.10.03 13:49
Sorry, hab vergessen, dass das ein Delphi Forum ist und ich kein Delphi kann.
Den Typ unsigned char gibt es in C/C++, da kann man einfach schreiben:
Quelltext 1:
| unsigned char meinString[100]; |
Dann hat man einen String, in dem 255 (glaub ich) verschiedene Zeichen vorkommen können, ein normaler char hat nur die Hälfte. Vielleicht hilft dir das ja auch bei Delphi irgendwie  .

|
|
Maggi
      
Beiträge: 160
WIN XP, WIN 2003
D5 Enter D 2006
|
Verfasst: Fr 31.10.03 13:52
Hi,
Schau doch mal in der Hilfe unter "OemToAnsi" nach in der Gegend findest du einige Fkt die dir vielleicht weiter helfen!!
Gruß
Maggi
_________________ "Wir haben den Kontakt zur Realität verloren, aber die findet uns schon wieder"
|
|
Killi 
      
Beiträge: 299
Win*
D6 Prof
|
Verfasst: Mo 03.11.03 12:19
Das bringt mich doch alles nicht weiter, ich weiß genau dass ich die Daten in ASCII bekomme...ist etwas an der ASCII-Funktion falsch? Bekomme ja keinen Wert wie 255 oder so....weiß nicht mehr weiter!!!
|
|
Brueggendiek
      
Beiträge: 304
Win 98, Win98SE, Win XP Home
D5 Std
|
Verfasst: Mo 03.11.03 23:47
Hallo Killi!
Nach der beliebten Winzig-Weich-Methode "Halte Dich nie an bestehende Standards, was WinzigWeich sagt, ist der neue Standard" hat der große Billy-Boy-Gates-jetzt-endlich beschlossen, daß Windows nicht mit dem ASCII-Code, sondern mit dem ANSI-Code arbeitet. Damit ist per WinzigWeicher Verfügung der bisherige Standard ASCII ungültig.
ASCII ist im Original ein 7-Bit-Code. Früher wurde bei Modem-Übertragung oft noch ein Paritätsbit verwendet, man übertrug 7 Bit + Parität, also 8 Bit zusammen.
Inzwischen gibt es einen ASCII-Standard, der mit 8 Bit arbeitet und damit auch so schöne Dinge wie Umlaute und Rahmengrafik (Blockgrafik) enthält.
Der ANSI-Code von Windows entspricht in den ersten 128 Zeichen dem ASCII-Code (7-Bit-Code). Die Zeichen ab $80 werden jedoch komplett anders belegt und sind somit nicht kompatibel zu ASCII. Insbesonders fehlen die Blockgrafikzeichen.
Bei Windows wird der ASCII-Zeichensatz als OEM-Zeichensatz bezeichnet. Damit sollte die Funktion "OEMtoANSI" einen ASCII-String - soweit die Zeichen definiert sind - in den Windows-Zeichensatz umwandeln.
Wenn Du Sicher bist, daß es ASCII ist, sollte die genannnte Funktion helfen. Wenn nicht, hilft nur das Ausprobieren, d.h. Karten mit Umlauten in den Namen organisieren und nachsehen, was da kommt. Dann mit Stringreplace oder durch zeichenweises Bearbeiten eine eigene Umwandlung realisieren.
Gruß
Dietmar Brüggendiek
|
|
Killi 
      
Beiträge: 299
Win*
D6 Prof
|
Verfasst: Di 04.11.03 11:50
Danke für die klärende Antwort!
Strreplace hätt ich schon lange gemacht, (bin ja faul) aber das geht eben nicht, da lles als "}" angezeigt wird, ist ja die sch...! Gut, ich teste es mal mit OEMToANSI!
|
|
Killi 
      
Beiträge: 299
Win*
D6 Prof
|
Verfasst: Di 04.11.03 12:26
Titel: hm...
...hier der neue Code, vielleicht hab ichs ja auch falsch eingebunden, OEMtoANSI steht jetzt VOR der "normalen" Textausgabe, aber es tut sich gar nix:
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87: 88: 89: 90: 91: 92: 93: 94: 95: 96: 97: 98: 99: 100: 101: 102: 103: 104: 105: 106: 107: 108: 109: 110: 111: 112: 113: 114: 115: 116: 117: 118:
| procedure TFormMain.ExecSCardCmd(Cmd,DataIn: String); const BufferSize = 32768; var P,pDataIn: PChar; DataASCII, DataHex, DataInHex: String; C: Integer; Len, LenIn: LongInt; begin MemoDataOut.Clear; if (Cmd = '') then begin MemoDataOut.Lines.Add('no command'); exit; end; with EditDataIn do if ((Font.Color=clRed) and (Text='(nil)')) then DataIn:=''; ShowCommand(Cmd,DataIn); P:=AllocMem(BufferSize); if DataIn='' then begin pDataIn:=nil; LenIn:=0; end else begin if RadioButtonHEX.Checked then begin DataInHex:=HexStrToTxt(DataIn); EditDataIn.Text := TxtToHexStr(DataInHex); LenIn := Length(DataInHex); pDataIn:=@DataInHex[1]; end else begin LenIn := Length(DataIn); pDataIn:=@DataIn[1]; end; end;
MemoDataOut.Lines.Add('executing command....'); try
Len:=SmartCard.Comand(Cmd,pDataIn,LenIn,P,BufferSize);
if Len = 0 then begin MemoDataOut.Lines.Add('command successful'); end else begin MemoDataOut.Font.Name:='Courier'; MemoDataOut.Font.Style:=[]; MemoDataOut.Lines.Add('DataOut in HEX:'); MemoDataOut.Lines.Add(' '); DataHEX:=''; for C:=0 to Len-1 do begin DataHEX:=DataHEX+IntToHex(Ord(P[C]),2)+' '; if (Length(DataHex)=48) then begin DataHEX:=DataHEX+' ['+IntToStrEx(C,3)+']'; MemoDataOut.Lines.Add(DataHEX); DataHEX:=''; end; end; if DataHEX <> '' then begin while Length(DataHEX)<49 do DataHEX:=DataHEX+' '; DataHEX:=DataHEX+'['+IntToStrEx(C,3)+']'; MemoDataOut.Lines.Add(DataHex); end; MemoDataOut.Lines.Add(' '); MemoDataOut.Lines.Add('DataOut in ASCII:'); MemoDataOut.Lines.Add(' '); DataASCII:='';
OEMtoAnsi(P, P); for C:=0 to Len-1 do begin case P[C] of #0..#31: DataASCII:=DataASCII+'°';
else DataASCII:=DataASCII+P[C]; end; if ((Length(DataASCII)>32) or (P[C]=#13)) then begin if (P[C]=#13) then begin while Length(DataASCII)<37 do DataASCII:=DataASCII+' '; DataASCII:=DataASCII+'(#13 found) '; end else while Length(DataASCII)<49 do DataASCII:=DataASCII+' '; MemoDataOut.Lines.Add(DataASCII+'['+IntToStrEx(C,3)+']'); DataASCII:=''; end; end; if DataASCII <> '' then begin while Length(DataASCII)<49 do DataASCII:=DataASCII+' '; MemoDataOut.Lines.Add(DataASCII+'['+IntToStrEx(C,3)+']'); end; end; except on E:ESmartCard do begin MemoDataOut.Lines.Add(' '); MemoDataOut.Lines.Add('SmartcardException: '+E.Message); end; on E:Exception do begin MemoDataOut.Lines.Add(' '); MemoDataOut.Lines.Add('Exception: '+E.Message); end; end; FreeMem(P,BufferSize); end; |
Moderiert von tommie-lie: Code- durch Delphi-Tags ersetzt
_________________ ----
Life is hard and then you die
|
|
elysm
      
Beiträge: 25
D6 Enter, D6 Pers, D7 Pro
|
Verfasst: Mi 05.11.03 10:58
Zitat: | Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12:
| for C:=0 to Len-1 do begin case P[C] of #0..#31: DataASCII:=DataASCII+'°';
// #132: DataASCII:=DataASCII+'ä'; // #142: DataASCII:=DataASCII+'Ä'; // #129: DataASCII:=DataASCII+'ü'; // #154: DataASCII:=DataASCII+'Ü'; // #148: DataASCII:=DataASCII+'ö'; // #153: DataASCII:=DataASCII+'Ö'; // #225: DataASCII:=DataASCII+'ß'; else DataASCII:=DataASCII+P[C]; | |
nimm doch einfach mal die slash´s vor den angaben weg!! das wäre das erste gewesen was ich gemacht hätte!
es sei den du hast die dahin gemacht.. denn hab ich nix gesagt! 
|
|
Killi 
      
Beiträge: 299
Win*
D6 Prof
|
Verfasst: Mi 05.11.03 11:37
die hab ich dahin gemacht weils nix bringt......das is ja die scheibenwischanlage
_________________ ----
Life is hard and then you die
|
|