AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Programmieren allgemein Codeschnipsel von GO zu Delphi übersetzen.
Thema durchsuchen
Ansicht
Themen-Optionen

Codeschnipsel von GO zu Delphi übersetzen.

Ein Thema von Newa · begonnen am 20. Okt 2015 · letzter Beitrag vom 21. Okt 2015
Antwort Antwort
Newa

Registriert seit: 10. Dez 2011
5 Beiträge
 
#1

Codeschnipsel von GO zu Delphi übersetzen.

  Alt 20. Okt 2015, 05:53
Hallo Werte Delphianer,
ich hab hier ein paar Zeilen Code die in GO geschrieben sind. Ich möchte dies in meinem Delphi XE3 nachbilden.
Mir fehlt das Verständnis für GO deswegen würde ich mich über Hilfe sehr freuen.

GO Code:
Adds non-Steam games that have been registered locally.
Code:
// This information is in the file config/shortcuts.vdf, in binary format.
// It contains the non-Steam games with names, target (exe location) and
// tags/categories. To create a grid image we must compute the Steam ID, which
// is just crc32(target + label) + "02000000", using IEEE standard polynomials.
func addNonSteamGames(user User, games map[string]*Game) {
   shortcutsVdf := filepath.Join(user.Dir, "config", "shortcuts.vdf")
   if _, err := os.Stat(shortcutsVdf); err != nil {
      return
   }
   shortcutBytes, err := ioutil.ReadFile(shortcutsVdf)
   if err != nil {
      return
   }

   // The actual binary format is known, but using regexes is way easier than
   // parsing the entire file. If I run into any problems I'll replace this.
   gamePattern := regexp.MustCompile("(?i)appname\x00(.+?)\x00\x01exe\x00(.+?)\x00\x01.+?\x00tags\x00(.*?)\x08\x08")
   tagsPattern := regexp.MustCompile("\\d\x00(.+?)\x00")
   for _, gameGroups := range gamePattern.FindAllSubmatch(shortcutBytes, -1) {
      gameName := gameGroups[1]
      target := gameGroups[2]
      uniqueName := bytes.Join([][]byte{target, gameName}, []byte(""))
      // Does IEEE CRC32 of target concatenated with gameName, then convert
      // to 64bit Steam ID. No idea why Steam chose this operation.
      top := uint64(crc32.ChecksumIEEE(uniqueName)) | 0x80000000
      gameId := strconv.FormatUint(top<<32|0x02000000, 10)
      game := Game{gameId, string(gameName), []string{}, "", nil}
      games[gameId] = &game

      tagsText := gameGroups[3]
      for _, tagGroups := range tagsPattern.FindAllSubmatch(tagsText, -1) {
         tag := tagGroups[1]
         game.Tags = append(game.Tags, string(tag))
      }
   }
}
Der Code ist Opensource und hat zum Ziel für die Plattform Steam einen Unique Hash aus Dateipfad und Name zu berechnen.

Ich bin die Sache so angegangen das ich einen string mit crc32 gehashed habe. Das Ergebnis ist ein DWord mit 10 stellen. Im oberen Code wird daraus ein 64 bit Unisgned Integer gemacht. Hier fehlen mir die Kenntnisse. Wie bilde ich das in Delphi ab? Im Grunde möchte ich also die gameid ermitteln.
Gruß

Geändert von TBx (20. Okt 2015 um 06:16 Uhr) Grund: Code-Tags eingefügt, bitte zukünftig selber machen. Danke! MfG TBx
  Mit Zitat antworten Zitat
TiGü

Registriert seit: 6. Apr 2011
Ort: Berlin
3.074 Beiträge
 
Delphi 10.4 Sydney
 
#2

AW: Codeschnipsel von GO zu Delphi übersetzen.

  Alt 20. Okt 2015, 08:33
Ich bin die Sache so angegangen das ich einen string mit crc32 gehashed habe. Das Ergebnis ist ein DWord mit 10 stellen. Im oberen Code wird daraus ein 64 bit Unisgned Integer gemacht. Hier fehlen mir die Kenntnisse. Wie bilde ich das in Delphi ab? Im Grunde möchte ich also die gameid ermitteln.
Gruß
Irgendwie so in der Art?

Delphi-Quellcode:
var
  Hash: IdHashCRC.TIdHashCRC32;
  uniqueName: string;
  gameID: string;
  HashedValue: UInt32;
  top: UInt64;
begin
  uniqueName := 'Beispiel_Name';
  Hash := TIdHashCRC32.Create;
  try
    HashedValue := Hash.HashValue(uniqueName);
  finally
    Hash.Free;
  end;

  top := HashedValue or $80000000;
  top := top shl 32 or $02000000;
  gameID := System.SysUtils.IntToHex(top, 10);
  gameID := System.SysUtils.LowerCase(gameID);
end;
Ggf. musst du ein mit den Anzahl der Stellen bei der IntToHex-Funktion experimentieren.
Die Verwendung von LowerCase deswegen, weil die FormatUint-Funktion Kleinbuchstaben zurückliefert :
https://golang.org/pkg/strconv/#FormatUint
  Mit Zitat antworten Zitat
Newa

Registriert seit: 10. Dez 2011
5 Beiträge
 
#3

AW: Codeschnipsel von GO zu Delphi übersetzen.

  Alt 20. Okt 2015, 20:24
Danke erstmal für die Ausführungen,
leider komme ich auf nach wie vor falsche Ergebnisse. (immerhin jetzt aber wohl in 64 bit string)

Code:
uniqueName := bytes.Join([][]byte{target, gameName}, []byte(""))
Diese Zeile bereitet mir Kopfschmerzen.

Ich habe das in Delphi einfach uniqueName := target+gameName und das Ergebnis dann gehashed.

Eigenartiger weise bekomme ich in xe3 nach shl 32 or $02000000 oftmal negative Werte - wie kann das sein?

Muss ich die Strings erst in ein ByteArray zerlegen und die Summen adderen?
  Mit Zitat antworten Zitat
TiGü

Registriert seit: 6. Apr 2011
Ort: Berlin
3.074 Beiträge
 
Delphi 10.4 Sydney
 
#4

AW: Codeschnipsel von GO zu Delphi übersetzen.

  Alt 21. Okt 2015, 08:54
Danke erstmal für die Ausführungen,
leider komme ich auf nach wie vor falsche Ergebnisse. (immerhin jetzt aber wohl in 64 bit string)
Was sind denn eigentlich die richtigen Ergebnisse?
Vielen hier, also auch mir, sind weder die Programmierung gegen die Steam-API noch die Programmiersprache Go bekannt, so dass wir ein bisschen mehr Informationen benötigen.
Hier wäre eine Aufstellung nach "gegeben" und "gesucht" hilfreich.
Also welche Eingangsparameter hast du und was erwartest du als Ausgangswert? Beispiele!

Code:
uniqueName := bytes.Join([][]byte{target, gameName}, []byte(""))
Diese Zeile bereitet mir Kopfschmerzen.
Ich habe das in Delphi einfach uniqueName := target+gameName und das Ergebnis dann gehashed.
Das war im ersten Beitrag nicht ersichtlich.
Ich nahm an, das dies schon gelöst war.

Eigenartiger weise bekomme ich in xe3 nach shl 32 or $02000000 oftmal negative Werte - wie kann das sein?
Muss ich die Strings erst in ein ByteArray zerlegen und die Summen adderen?
Wie sind denn deine Vorkenntnisse in Sachen Programmierung?
Ist dir klar was die Operatoren shl und or bewirken sollen?

Hast du dich mit den Go-Quelltext mal auseinandergesetzt?
Google bietet mit dem Playground ja die schnelle Möglichkeit des Ausprobierens:
https://play.golang.org/

Teste doch mal folgenden Quelltext im Playground, vielleicht wird dir dann klarer, wie du weiter vorgehen musst.
Code:
package main

import (
   "bytes"
   "fmt"
)

func main() {

   target := []byte("Hello")
   gameName := []byte(" World!")

   uniqueName := bytes.Join([][]byte{target, gameName}, []byte(""))
   fmt.Println("uniqueName")
   fmt.Println(" ")
   fmt.Println("as byte array:")
   fmt.Println(uniqueName)
   fmt.Println(" ")
   fmt.Println("as string:")
   fmt.Println(string(uniqueName))
}
  Mit Zitat antworten Zitat
Benutzerbild von Union
Union

Registriert seit: 18. Mär 2004
Ort: Luxembourg
3.492 Beiträge
 
Delphi 7 Enterprise
 
#5

AW: Codeschnipsel von GO zu Delphi übersetzen.

  Alt 21. Okt 2015, 09:04
Eigenartiger weise bekomme ich in xe3 nach shl 32 or $02000000 oftmal negative Werte - wie kann das sein?
Das kann nur sein, wenn Du nicht durchgängig UINT Werte verwendest oder sie für die Anzeige falsch umwandelst. Woher weisst Du denn dass das Ergebnis negativ ist?
Ibi fas ubi proxima merces
sudo /Developer/Library/uninstall-devtools --mode=all
  Mit Zitat antworten Zitat
Newa

Registriert seit: 10. Dez 2011
5 Beiträge
 
#6

AW: Codeschnipsel von GO zu Delphi übersetzen.

  Alt 21. Okt 2015, 09:52
Also,
im Grunde sind alle Probleme behoben. Byte.join setzt einfach nur einen String zusammen und setzt "" als Delimiter. Genau da lag das Problem. Das hab ich überlesen. Ich habe also einen inkorrekten string gehashed.
shl 32 versetzt die bytes nach links um einen Uint64 erhalten. Das klappt soweit. Ich muss mich mehr mit den Typen wie int,uint,dword auseinandersetzen. Da hab ich deutlich nachhole Bedarf.

Gelöst hab ich das nun wie oben im Beispiel von TiGü beschrieben.

Code:
function TForm1.HashIt(PathWithQuotesAndNameString : string) : string;
var
   //Hash: IdHashCRC.TIdHashCRC32;
   HashedValue: DWord;
   top111: UInt64;
   Hex : string;
begin
   result := 'NO HASH';
   //PathWithQuotesAndNameString := '"C:\Program Files\Games\Fifa 14\fifa14.exe"FIFA 14';
   CalcStringCRC32(PathWithQuotesAndNameString, HashedValue);
   top111 := HashedValue or $80000000;
   top111 := top111 shl 32 or $02000000;
   result := IntToStr(top111);
end;

// Ergibt im Beispiel result = 10849726566762545152
Code ist hier in FreePascal so lauffähig und funktioniert.

Danke TiGü

Ps. In XE3 nutze ich das Firemonkey Framework. Könnte da der Fehler in IntToStr(top111) mit den negativen Werten liegen?

Geändert von Newa (21. Okt 2015 um 09:57 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Union
Union

Registriert seit: 18. Mär 2004
Ort: Luxembourg
3.492 Beiträge
 
Delphi 7 Enterprise
 
#7

AW: Codeschnipsel von GO zu Delphi übersetzen.

  Alt 21. Okt 2015, 09:59
Das liegt nicht an Firemonkey. Verwende lieber explizit UIntToStr.
Ibi fas ubi proxima merces
sudo /Developer/Library/uninstall-devtools --mode=all
  Mit Zitat antworten Zitat
TiGü

Registriert seit: 6. Apr 2011
Ort: Berlin
3.074 Beiträge
 
Delphi 10.4 Sydney
 
#8

AW: Codeschnipsel von GO zu Delphi übersetzen.

  Alt 21. Okt 2015, 10:05
Ps. In XE3 nutze ich das Firemonkey Framework. Könnte da der Fehler in IntToStr(top111) mit den negativen Werten liegen?
Wegen Firemonkey nicht, aber bei sehr großen unsigned Zahlen läuft IntToStr sozusagen über.
Nehme besser die UIntToStr-Funktion!
Zu jedem Datentyp die passende Funktion wählen!
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 22:38 Uhr.
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz