Ich bin vor einigen Jahren auf ein interessantes theoretisches Problem gestoßen. Ich habe nie eine Lösung gefunden, und sie verfolgt mich weiter, wenn ich schlafe.
Angenommen, Sie haben eine (C #) - Anwendung, die eine Zahl in einem int enthält, genannt x. (Der Wert von x ist nicht festgelegt). Wenn das Programm ausgeführt wird, wird x mit 33 multipliziert und dann in eine Datei geschrieben.
Der grundlegende Quellcode sieht folgendermaßen aus:
int x = getSomeInt();
x = x * 33;
file.WriteLine(x); // Writes x to the file in decimal format
Einige Jahre später stellen Sie fest, dass Sie die ursprünglichen Werte von X zurück benötigen. Einige Berechnungen sind einfach: Teilen Sie einfach die Zahl in der Datei durch 33. In anderen Fällen ist X jedoch groß genug, dass die Multiplikation einen Ganzzahlüberlauf verursacht. Gemäß den Dokumenten schneidet C # die höherwertigen Bits ab, bis die Zahl kleiner als ist int.MaxValue
. Ist es in diesem Fall möglich, entweder
- Stellen Sie X selbst wieder her oder
- Eine Liste der möglichen Werte für X wiederherstellen?
Es scheint mir (obwohl meine Logik sicherlich fehlerhaft sein könnte), dass einer oder beide möglich sein sollten, da der einfachere Fall der Addition funktioniert (im Wesentlichen, wenn Sie 10 zu X addieren und es umschließt, können Sie 10 subtrahieren und wieder mit X aufwickeln ) und Multiplikation wird einfach Addition wiederholt. Ebenfalls hilfreich (glaube ich) ist die Tatsache, dass X in allen Fällen mit dem gleichen Wert multipliziert wird - eine Konstante von 33.
Das tanzt seit Jahren in seltsamen Momenten um meinen Schädel. Es wird mir einfallen, ich werde einige Zeit damit verbringen, darüber nachzudenken, und dann werde ich es für ein paar Monate vergessen. Ich bin es leid, dieses Problem zu verfolgen! Kann mir jemand einen Einblick geben?
(Randnotiz: Ich weiß wirklich nicht, wie ich diesen taggen soll. Vorschläge erwünscht.)
Bearbeiten: Lassen Sie mich klarstellen, dass ich, wenn ich eine Liste der möglichen Werte für X erhalten kann, andere Tests durchführen kann, um sie auf den ursprünglichen Wert einzugrenzen.
m
nur 2 ^ 32 oder 2 ^ 64 ist und die Exponentiation von a
Modulo m
einfach ist (ignorieren Sie einfach den Überlauf dort)
r*s^-1 mod m
Sie und müssen beides r
und finden s
. Hier haben wir r*s mod m
und wir wissen alles aber r
.