Kilka lat temu natrafiłem na ciekawy problem teoretyczny. Nigdy nie znalazłem rozwiązania i nadal mnie prześladuje, kiedy śpię.
Załóżmy, że masz aplikację (C #), która zawiera pewną liczbę w int, o nazwie x. (Wartość x nie jest stała). Po uruchomieniu programu x jest mnożone przez 33, a następnie zapisywane w pliku.
Podstawowy kod źródłowy wygląda następująco:
int x = getSomeInt();
x = x * 33;
file.WriteLine(x); // Writes x to the file in decimal format
Kilka lat później odkrywasz, że potrzebujesz oryginalnych wartości X. Niektóre obliczenia są proste: wystarczy podzielić liczbę w pliku przez 33. Jednak w innych przypadkach X jest wystarczająco duży, aby zwielokrotnienie spowodowało przepełnienie liczb całkowitych. Zgodnie z dokumentacją , C # obetnie bity wysokiego rzędu, aż liczba będzie mniejsza niż int.MaxValue. Czy w tym przypadku można:
- Odzyskaj sam X lub
- Odzyskać listę możliwych wartości dla X?
Wydaje mi się (choć moja logika mogłaby być z pewnością błędna), że jeden lub oba powinny być możliwe, ponieważ prostszy przypadek dodawania działa (Zasadniczo, jeśli dodasz 10 do X i zostanie on zawinięty, możesz odjąć 10 i skończyć z X ponownie ), a mnożenie jest po prostu powtarzanym dodawaniem. Pomagam również (jak sądzę) fakt, że X jest mnożony przez tę samą wartość we wszystkich przypadkach - stałą 33.
Od lat tańczy to wokół mojej czaszki. Przychodzi mi do głowy, poświęcę trochę czasu na przemyślenie tego, a potem zapomnę o tym na kilka miesięcy. Mam dość pogoni za tym problemem! Czy ktoś może zaoferować wgląd?
(Uwaga dodatkowa: Naprawdę nie wiem, jak oznaczyć ten tag. Sugestie mile widziane.)
Edycja: Pozwól mi wyjaśnić, że jeśli mogę uzyskać listę możliwych wartości dla X, są inne testy, które mogę zrobić, aby pomóc mi zawęzić ją do pierwotnej wartości.
mwynosi tylko 2 ^ 32 lub 2 ^ 64, a potęgowanie amodulo mjest proste (po prostu zignoruj tam przepełnienie)
r*s^-1 mod mi musisz znaleźć zarówno ri s. Tutaj mamy r*s mod mi wiemy wszystko, ale r.