קוד נגדי קצר
-
אני מחפש פתרון קוד, שאוכל להביא ללקוח קוד בן 5 ספרות, ולפי זה לזהות מספר טלפון בן 10 ספרות.
אני לא צריך אבטחת מידע או משהו, רק שלא יביא לי מס' טלפון של מישהו אחר בטעות.לדוגמה: הלקוח יספק לי מס' טלפון : 0527123456, והתוכנה תביא לו את הקוד: 72589.
ואז כשהלקוח יספק את הקוד 72589, התוכנה תדע לשלוף את המספר 0527123456 ללא שימוש ב DB.
אפשרי?תודה!
-
@WWW הדרך הקלה ביותר היא להתעלם משלושת הספרות הראשונות של מספר הטלפון, ולהגדיר קוד נגדי באורך זהה של 7 ספרות.
הנה קוד פייתון פשוט מאוד שעושה את מה שאתה רוצה באמצעות תרגיל חשבוני פשוט.
ניתן כמובן לעשות את זה בכל שפת תכנות די בקלות.# Function to generate a 5-digit code from a phone number def generate_code(phone_number): # Extract the last 7 digits and add a constant (e.g., 1000000) code = str(int(phone_number[-7:]) + 1482673) return code # Function to reverse the code back to the phone number def get_phone_number(code): # Subtract the constant to get the last 7 digits phone_number = str(int(code) - 1482673) # Add leading zeros to make it 10 digits phone_number = phone_number.zfill(10) return phone_number # Test it out phone_number = "0527123456" code = generate_code(phone_number) print("Generated Code:", code) retrieved_number = get_phone_number(code) print("Retrieved Phone Number:", retrieved_number)
בקצרה: הקוד מכיל 2 פונקציות, אחת שיוצרת קוד לפי מספר טלפון, ואחת שמזהה את מספר הטלפון המקורי לפי הקוד.
כל מה שהפונקציות עושות זה להוסיף או להפחית את המספר 1482673 מהמספר שהפונקציה מקבלת
באותה מידה ניתן גם להכניס את המספר 3457891 או כל מספר אחר באורך של 7 ספרות
-
המשימה הזו (להפוך קלט גדול לפלט קטן שמייצג אותו בצורה נאמנת) נקראת גיבוב.
במקרה הזה נצורך הוא בגיבוב לא למטרות אבטחה (כי לא אכפת לנו שיהיה דרך להפוך או לנחש דרך הפלט מידע כל שהוא על הקלט). יש כמה אלגוריתמים לזה.
בPH הפונקציה hash מקבלת פרמטר של אלגוריתם מתוך רשימה מכובדת של אפשרויות, אבל אף אחד לא מחזיר קלט כה קצר של 5 ספרות (שזה ב בתים בערך בלבד), פה מציעים לקצץ את התוצאה: https://stackoverflow.com/questions/3379471/php-number-only-hash
אולי יותר יעיל לממש לבד גיבוב פשוט, אני לא יודע לעשות זאת.עריכה: @nigun העיר לי שלא קראתי טוב את השאלה. השאלה רוצה גיבוב הפיך, כלומר שיוכלו אחר כך להסיק מהפלט הקטן חזרה את הקלט הגדול, משהו כמו דחיסת נתונים. בקלט כה קטן בלתי אפשרי לחסוך אפילו לא בספרה אחת. אפשר לבדוק את כל קידומות הטלפונים (05271, 05048 וכולי) עד ארבע או חמש ספרות, ולבדוק אם זה פחות מ100 אפשרויות ואז שוב נצטרך מילון, שזה כבר סוג של DB.
-
אין לי פתרון סופי, אבל כיוון למחשבה,
כל מספר טלפון(לכה"פ נייד) הוא בעצם מספר שהמינימום שלו הוא 500 מליון
והמקסימום שלו הוא 589 מליון
(ניכוי האפס בהתחלה, וההנחה שכל מספרים הניידים מתחילים ב 05)
אם נחסר מהמספר, 500 מליון ומשהו (כמובן שזה יהיה תמיד מספר קבוע) נקבל בסוף מספר יותר קצר
נ.ב. ניסיתי לעשות כמה ניסויים ולא הצלחתי, לכן אני מעלה רק כיוון ויתכן מאוד שאני תועה
עוד נ.ב. כרגע פיתרון זה לא פותר מספרים נייחים ומספרים מחול ומספרים המתחיל ב 07
מקווה שלא הטרחתי -
@לעזור-לכולם 500 מליון או 900 מליון זה חסר משמעות. מכיון שבסוף שתי הסכומים הם בעלי 8 אפסים, כך שבפועל המספר לא מקוצר כלל
-
@NH-LOCAL כתב בקוד נגדי קצר:
@לעזור-לכולם 500 מליון או 900 מליון זה חסר משמעות. מכיון שבסוף שתי הסכומים הם בעלי 8 אפסים, כך שבפועל המספר לא מקוצר כלל
לא הבנתי, אם מחסירים ממספר הטלפון סכום מסויים (של 9 ספרות) אז בהכרח המספר מתקצר
ומכיל מקסימום 7/8 ספרות
איפה, אני טועה? -
@WWW במקרה שלך זה בלתי אפשרי לייצר מספר בן 10 ספרות ממספר בן 5 ספרות.
הפתרון הוא שהקוד הנגדי יהיה באורך של 8 ספרות (זהה לאורך של מספר פלא' חוץ מהקידומת הקבועה 05, כמו שכתבו פה) ואז להפוך את המספר פלאפון איכשהו (xor לדוגמא) לקוד הנגדי, ובאותה דרך לשחזר למספר הפלאפון שהמשתמש הזין.
-
@חגי כתב בקוד נגדי קצר:
הקוד הנגדי חייב להיות מספרים?
אם משתמשים בקודי ascii אפשר ליצור מ-8 ספרות קוד של 4 ספרות, ולהמיר אותם בחזרה למספר
לדוגמה (בהנחה שמורידים את שתי הספרות הראשונות):
rg`y = 27168934
MF!r = 48416227
(יש ברשותי את הקוד המלא אם יהיה בזה עניין למישהו)
-
הרעיון די פשוט והוא עלה בדעתי תוך כדי הדיון כאן. הביצוע ברובו הוא צ'אט GPT. קוד פייתון כמובן.
import string def create_dict(): # Initialize an empty dictionary ascii_dict = {} # Loop through numbers from 0 to 99 for num in range(100): # Convert the number to a two-digit string num_str = f"{num:02d}" # Get the corresponding ASCII character using the number as an index ascii_char = string.printable[num] # Add the number and its corresponding ASCII character to the dictionary ascii_dict[num_str] = ascii_char return ascii_dict def hash_phone(phone_number): # Ensure the input phone_number is a string of 8 digits if not isinstance(phone_number, str) or len(phone_number) != 8 or not phone_number.isdigit(): raise ValueError("Invalid phone number. Please provide an 8-digit string of numbers.") # Create the dictionary (you can use your 'create_dict' function here) ascii_dict = create_dict() # Initialize an empty string to store the resulting ASCII characters ascii_result = "" # Convert each pair of digits to corresponding ASCII characters for i in range(0, len(phone_number), 2): num_pair = phone_number[i:i + 2] if num_pair in ascii_dict: ascii_result += ascii_dict[num_pair] else: raise ValueError(f"No dictionary entry found for {num_pair}") return ascii_result def unhash_phone(ascii_code): # Ensure the input is a string of 4 ASCII characters if not isinstance(ascii_code, str) or len(ascii_code) != 4: raise ValueError("Invalid ASCII code. Please provide a string of 4 ASCII characters.") # Create the dictionary (you can use your 'create_dict' function here) ascii_dict = create_dict() # Initialize an empty string to store the resulting number phone_number = "" # Convert each ASCII character back to the original number pair for char in ascii_code: found = False for num_pair, ascii_char in ascii_dict.items(): if ascii_char == char: phone_number += num_pair found = True break if not found: raise ValueError(f"No dictionary entry found for ASCII character: {char}") # Convert the resulting string of number pairs back to an integer return phone_number code = hash_phone('48416227') print(code) print(unhash_phone(code))
-
הרעיון שלי היה לעשות המרת בסיסים, להמיר מבסיס 10 לבסיס 32 (בדקתי בגוגל, זה יוצא 6 ספרות.. אז זה לא מתאים, בבסיס 60 זה נראה טוב ובלי תווים מוזרים)
https://math.tools/calculator/base/10-60 -
-
@dovid כתב בקוד נגדי קצר:
@חגי בסיס זה סה"כ שימוש באותיות כספרות נוספות, אז זה זהה למה שהציע @NH-LOCAL רק שהוא לא קרא לזה באותו שם. base64 זה בסיס נפוץ מאוד שיש בכל שפה פונקציה ישירה לייצר אותו ובבסיס הזה בחמש תווים יש די והותר.
כל ההסתעפות הזו היא ספקולציה למה הצורך של @WWW שלבטח רצה נטו ספרות ולא שום דבר אחר...
בבסיס 64 (המובנה) יש לך ריפוד ב
=
וגם סימני+
//
שנראים פחות טוב. (וגם ההמרה המובנית היא בד"כ מbuffer\מחרוזת, ולא ממספר) סתם נראה לי שיותר קל לתת קוד נגדי בלי סלאש ("זה סלאש קדימה או אחורה? איזה כיוון זה סלאש אחורה? אהה.. זה איפה שהנקודה במקלדת.. רגע זה עשה לי נקודה, אהה.. אתה מתכוון איפה שהQ, אוקיי יש פה סלאש אחורה.. כלומר קדימה.. נו מה שאמרת..)
אם יש שם backtick\טילדה, אני מאחל הרבה הצלחה בהעברה בעל פה של התו
("תעשה טילדה, זה שיפט + בקטיק, זה איפה שהנקודה פסיק כשאתה על עברית, אל תשכח שיפט!!! אוקיי מה המייל שלך אני אעביר לך את הקוד נגדי במייל")(בעיקרון גם base62 יעשה את העבודה, זה הכי גבוה שאפשר בלי תווים שאינם אותיות ומספרים)