קומפיונט
-
הוספת תיקיה מוכרת מותאמת אישית ב-Windows -
תרגיל מתמטי של הסתרת מזהה רץ@dovid אני אוהב לעזור לכל מי שמבקש, התחום שאני חזק בו זה #C ו WPF, ובינתיים לא נתקלתי בבקשת עזרה בתחום הזה. אם אני יתקל בבקשת עזרה בתחום הזה, אהיה בל"נ הראשון שיעזור.
רוב השאלות שראיתי פה בפורום הם בנושא VBA או WinForm שאני לא מומחה בהם, בלשון המעטה.
עכשיו לגבי הקוד שפורץ את הרעיון, אני חושב שאני לא צריך להסביר לך שזה בגלל שהמפתחות שהקוד שהכנתי מייצר הם מפתחות קטנים, ולכן קל לשחזר אותם. אני בחרתי לייצר מספרים קטנים רק בגלל שיקולים של ביצועים.
קח לדוגמא את הספרות האלו:
1194494
719311
1944435
1477276
874876
1765046
1615810
1097120
1085181
1495561
1968819
1743848
171395
217310
1476345אני משוכנע שזה כמעט לא אפשרי לשחזר את המפתח המקורי שלהם, (אולי זה ייקח כמה שנים...) וזה בגלל שעכשיו בחרתי למפתחות מספרים די גבוהים.
-
תרגיל מתמטי של הסתרת מזהה רץאני רוצה להוסיף עוד משהו קטן.
עכשיו קראתי בויקיפדיה על ה-RSA והתבאר לי משהו שלא היו מובן לי עד עכשיו.
אם אני מצפין באמצעות התרגיל שהצגתי (שהוא כאמור RSA) את הספרה 1 אז גם זה הפלט המוצפן (משום שהכפלה של 1 תמיד תחזיר 1) אז יש פה איזה חולשה.קראתי שם על עוד כמה חולשות, לדוג' שאם הפורץ שולח קלט קצר והוא מקבל את התוכן המוצפן אז יתכן שהוא יוכל לפרוץ את זה בקלות (הבעיה המרכזית בנושא הזה).
אז הפתרון לבעיות האלו (שמשתמשים בו היום) הוא להשתמש עם ריפוד, ובעצם כבר הזכירו את זה פה @חגי ו @nigun שאפשר להשתמש עם מספרים רנדומליים שיטשטשו את המבנה של המספר המקורי.
אז המסקנה שלי שבשביל ערפול (או הצפנה) מוצלח צריך את שני הדברים הללו (התרגיל עצמו וטשטוש המבנה של ההודעה המקורית), וכל אחד בפני עצמו לא יהיה מספיק טוב.
אפשר לקרוא על זה פה תחת התת כותרת "ריפוד".
-
תרגיל מתמטי של הסתרת מזהה רץטוב, @dovid אני רוצה לחשוף את כל הקלפים.
עשיתי פה קונץ קטן, אנא קבל את התנצלותי "...ומודה ועוזב ירוחם".הפתרון שהצגתי הוא לא רעיון שלי (ודאי שלא, לא היתה הו"א בכלל) הוא פתרון שכיום נמצא בשימוש נרחב בתעשייה העולמית, ואפשר למצוא אותו כמעט בכל פינה. הפרוטוקולים המאובטחים של האינטרנט מבוססים עליו, והוא המלך של ההצפנות הא-סימטריות - הלא הוא ה-RSA!
אז כאמור, קבל את התנצלויותי על כך שלא חשפתי את הפרט הזה. חששתי להשתמש בנגזרת של צ.פ.נ. מפני שהבקשה הייתה מפורשת לא להשתמש בהצפנה אלא בתרגיל. ניסיתי להציע את זה בהתחלה (מבלי לצרף דוגמא), אבל אז חטפתי על הראש שלא קראתי היטב את השאלה. לכן בחרתי להציג את זה כתרגיל מתמטי ולא כהצפנה.
מה, וכי אני אשם שה-RSA משתמש בתרגיל המתמטי הפשוט הזה?!
@dovid נדמה לי שעכשיו אתה לא צריך הוכחות על הביטחון של התרגיל הזה.
-
תרגיל מתמטי של הסתרת מזהה רץ@dovid כתב בתרגיל מתמטי של הסתרת מזהה רץ:
בינתיים לא הצגת קוד זהב שעושה זאת בלי שום ידע מוקדם מלבד הנקודות שהזכרת (השיטה והרצף של ה30).
אני כבר אמרתי שאין לי משהו מיוחד בקוד, הסיבה הפשוטה שאני לא מביא אותו כאן זה בגלל שזה נמצא במקום אחר ולא על המחשב שאני כותב בו עכשיו, וגם שם אני לא בטוח שהוא נשאר בשלמותו.
אם אתה לא יודע להסביר את המתמטיקה, הבטחון שלך שקול בעיני לאמונה אינטואטיבית. אני נשנעתי על הסמכות של הכותבים של הרעיון.
אוקיי, בא נעשה סדר.
אתה יודע מי הכותבים האלה? אני לא מכיר אותם, ואני בטוח שזה לא רעיון שלהם, ועם כל זה הם כותבים במפורש שזה לא מוסיף אבטחה:this adds no actual security to a system; it’s obscurity, at best.
מי אני אתה גם לא יודע, אבל אני לפחות אומר לך במפורש שאם משתמשים במספרים גדולים, זה כן מוסיף אבטחה. אתה לא חייב לסמוך עלי, אבל זה דעתי. לתרום לדיון בעניין הזה כבר אמרתי שקשה לי (כי זה לא ברור לי דיו).
-
תרגיל מתמטי של הסתרת מזהה רץ@dovid החולשה של הפתרון שלך הוא בעיקר בגלל שאפשר לעלות עליו עם Brute Force, וזה בעצם הדבר שהתרגיל שהצגתי עושה אותו (הרבה) יותר קשה.
מבחינת המתמטיקה אני בטוח שאין דרך לפענח את זה. החולשה היחידה האפשרית זה Brute Force.
-
תוספים שימושיים לVSCיש ל-vscode המון הרחבות של ערכת נושא, אבל אני רוצה להביא שילוב של שני הרחבות שאני אישית מאוד אוהב, וזה אחרי בדיקה של עשרות themeים...
ההרחבות הם:
מצרף צילומי מסך:
זה הערכת נושא הכהה הרגילה של vscode:
וזה אחרי שני התוספים הנ"ל:
-
תרגיל מתמטי של הסתרת מזהה רץ@dovid
קשה לי להסביר למה הוא יותר טוב (משום שלי לא ברור עד הסוף), אבל הוא בטוח יותר טוב מסיבה פשוטה:
מתבצע בו העלאה בחזקה (במקום הכפלה בתרגיל שלך) שזה לוקח זמן למחשב, ולכן ל-Brute Force ייקח הרבה זמן.
לדוגמא, התוצאה של התרגיל הזה:12345 ** 12345
זה מספר עם 50,510 ספרות, אז בשביל פעם אחת האיטיות לא תהיה מורגשת, אבל לחישוב של אלפי מספרים האיטיות תהיה מורגשת מאוד.אבל זה גם לא מאה אחוז. ככל שהמספרים של המפתחות יהיו גדולים כך זה יהיה יותר בטוח (אבל גם איטי).
@dovid כתב בתרגיל מתמטי של הסתרת מזהה רץ:
יש לך מה להשתפשף בקידוד, כי הקוד לא מספיק טוב
אשמח אם תצביע לי על מקום שיכול להיכתב יותר טוב, ואני בל"נ אתקן.
-
תרגיל מתמטי של הסתרת מזהה רץ@dovid מצאתי פתרון אחר שקצת מזכיר את הרעיון שלך אבל הוא נראה לי יותר טוב.
התרגיל הזה קצת יותר 'יקר' למחשב כי הוא מחייב שימוש ב-BigInt, אבל הוא הרבה יותר בטוח וקשה לפענוח.
המפתחות הם כמו בתרגיל הקודם - שני מספרים כלשהם ומודולו שהוא המקסימום.היצירה של המפתחות בפעם הראשונה היא פעולה קצת מורכבת, אז הכנתי פונקציה ב-#C שתיצור את המפתחות.
יש שלושה מפתחות: d ,e ו - n, ה - n הוא המודולו והוא המספר המקסימלי שאפשר לערפל ולשחזר למספר המקורי.
אחרי שיש את המפתחות הערפול נעשה בצורה כזאת:id ** e % n
והשחזור למספר המקורי נעשה הפוך:obfuscated ** d % n
הפתרון הזה יותר לוקח זמן כי מתבצע בערפול ובשחזור העלאה בחזקה מה שלא היה בפתרון הקודם,
אז צריך לשקול מה יותר חשוב, האבטחה או הביצועים.זה הפונקציה ליצירת המפתחות: (GenerateKeys)
void GenerateKeys(out int n, out int e, out int d) { Random random = new(); int p = GeneratePrime(128, 512, random); int q = GeneratePrime(128, 512, random); n = p * q; int ef = Lcm(p - 1, q - 1); GenerateE: e = random.Next(32, 512); if (Gcd(e, ef) != 1) goto GenerateE; d = GenerateD(ef, e); if (d < 0) goto GenerateE; } bool IsPrime(int num) { for (int i = num - 1; i > 1; i--) { if (num % i == 0) return false; } return true; } int Gcd(int a, int b) { return b == 0 ? a : Gcd(b, a % b); } int Gcf(int a, int b) { while (b != 0) { int temp = b; b = a % b; a = temp; } return a; } int Lcm(int a, int b) { return a / Gcf(a, b) * b; } int GeneratePrime(int min, int max, Random random) { int p; do { p = random.Next(min, max); } while (!IsPrime(p)); return p; } int GenerateD(int ef, int e) { int y1 = 1, y2 = 0; while (e > 0) { int q = ef / e; int y = y2 - (q * y1); int r = ef % e; ef = e; e = r; y2 = y1; y1 = y; } return y2; }
בשביל למהר את הביצועים מומלץ להשתמש במפתחות עם המודולו הקטן ביותר שנצרך, לדוג' אם המספר הגבוה ביותר שצריך לעפל הוא 10,000, אז כדי לקרוא לפונקציה שיוצרת את המפתחות שוב ושוב עד שיצא מספר מקסימלי (n) הכי נמוך אבל מעל 10,000.
טסט לדוגמא ב-#C:
GenerateKeys(out var n, out var e, out var d); Console.WriteLine($"n: {n}, e: {e}, d: {d}"); foreach (var num in Enumerable.Range(3, 15)) { int c = (int)(BigInteger.Pow(num, e) % n); int m = (int)(BigInteger.Pow(c, d) % n); Console.Write("num: " + num); Console.CursorLeft = 15; Console.Write("c: " + c); Console.CursorLeft = 30; Console.WriteLine("m: " + m); }
הפלט:
n: 71219, e: 287, d: 12683 num: 3 c: 36878 m: 3 num: 4 c: 51738 m: 4 num: 5 c: 44630 m: 5 num: 6 c: 54772 m: 6 num: 7 c: 26540 m: 7 num: 8 c: 21046 m: 8 num: 9 c: 60079 m: 9 num: 10 c: 43447 m: 10 num: 11 c: 66289 m: 11 num: 12 c: 36954 m: 12 num: 13 c: 61380 m: 13 num: 14 c: 64087 m: 14 num: 15 c: 65269 m: 15
אשמח לקבל הארות ותגובות.
-
תרגיל: עיגול מספר לפי מערך מפתחות@dovid כתב בתרגיל: עיגול מספר לפי מערך מפתחות:
סליחה, בכל מקום שMath.Clamp יעבוד (CORE 2 ומעלה) זה בהכרח C# 7.3 לפחות.
הערת אגב: הפיצ'ר שכתבתי (
arr[^1]
) לא קיים ב C# 7.3, זה רק מ 9.0 או 8.0. -
תרגיל מתמטי של הסתרת מזהה רץ@dovid אמר בתרגיל מתמטי של הסתרת מזהה רץ:
שגוי לחלוטין. אין לך קצה חוט בעניין, מלבד הדוגמאות פה...
לכן כתבתי שאני מהמר, זה הבסיס להתחיל, אם זה לא יעבוד אני אמשיך אלאה. אני חושב שזה שגוי להתחיל את הניסיון לפענח בהנחה שהמספרים הם גדולים.
@dovid אמר בתרגיל מתמטי של הסתרת מזהה רץ:
למה אתה חושב שרסיס המידע הזה אינו קריטי לדיון פה בדיוק בנושא שדן אם זה מספיק מערפל? למה אתה צריך להתחבא מאחורי זה שהצלחת לפרוץ במקום לחשוף את החולשות שאותם הכרת והשתמשת בהם?
אם היינו דנים בזה אולי היה מישהו מצליח לקחת את מה שאמרת קדימה ולהוכיח שהמפתח חייב להיות לפחות פי שניים מאיבר הכי גדול וככה עוד יותר לקצר, ואולי גם להוכיח שהוא קטן ממספר מקסימלי אחר כדי להקטין את הסריקה למינימום. זה בדיוק המעלה של דיון בריא.
בכל אופן, השיפור הזה כשלעצמו עדיין מעייף את המחשב שלי דקות ארוכות ללא מענה, וכאומר כל המעבדים עובדים במלא הקיטור.כל הנושא הזה זה נשמע לי כמו מתקפה, אז הגבתי בהתאם.
-
תרגיל מתמטי של הסתרת מזהה רץ@dovid אמר בתרגיל מתמטי של הסתרת מזהה רץ:
אולי תגיד בדיוק מה עשית במקום שאני אעשה לך שש מבחנים?
כשאני מסתכל על רצף הספרות שעברו ערפול, לדוגמא:
699115, 1015520, 310513, 626918, 943323, 238316, 554721, 871126, 166119, 482524, 798929, 93922, 410327, 726732, 21725
אז אני יודע בוודאות שהמודולו הוא חייב להיות מספר יותר גבוה מהמספרים האלו, אז זה חייב להיות מעל 1015520 שזה המספר הכי גבוה ברשימה.
יש עוד כמה הנחות שאפשר להבין. לדוג' אם אני מהמר שהמספרים העוקבים (המקוריים) הם נמוכים יחסית, שזה מאוד הגיוני שזה ככה, אז מספר המפתח צריך להיות גדול מספיק כדי שהתוצאה של ההכפלה תעבור את מספר המודולו, כי אם זה לא יעבור אותו אז המספרים יראו עוקבים ולא מבולגנים.
-
תרגיל: עיגול מספר לפי מערך מפתחות@yossiz ממש אהבתי
אבל אם במערך יש מספרים שליליים זה נותן תוצאות לא צפויות.
אגב, אפשר לכתוב
keys[^1]
במקוםkeys[keys.Length - 1]
עריכה: מדובר בפיצ'ר די חדשני של #C.
-
תרגיל: עיגול מספר לפי מערך מפתחות@Y-Excel-Access יפה מאוד. אני לא בקיא ב-vb אז קצת קשה לי להבין את כל הקוד שכתבת. אבל מבדיקה מהירה שלי ראיתי שאם אני מכניס מספר יותר גבוה מהמספר המקסימאלי אז נזרקת שגיאה.
אגב, הקוד נראה לי קצת ארוך... אז בשביל התרגיל תנסה לקצר אותו כמה שאפשר, אני רואה ש@dovid כבר קיצר לך קצת.
-
תרגיל: עיגול מספר לפי מערך מפתחות@dovid אמר בתרגיל: עיגול מספר לפי מערך מפתחות:
א. אני גם תהיתי אם יום אחד תכתוב לנו את הקוד בו סרקת תוך שניות את הקוד ההוא של המודלו...
אין לי משהו מיוחד בקוד, זה brute force פשוט. העניין הוא מאיזה מספר להתחיל את הסריקה. לא התחלתי מאפס, כמובן.
שים לב שההצעה שלי לא יותר קצרה, ושים לב שלבקש קוד הכי קצר והכי יעיל זה כמו לבקש מכונית הכי מהירה ועם הכי הרבה מקום בו זמנית בלי להסביר לפי מה יחולק הציון בין שני הפרמטרים.
אם יש לך אחד משני הפרמטרים שהוא יותר טוב זה מספיק לי.
כולנו לעיתים כותבים קוד יותר קריא מאשר מהיר מבחינת ביצועים. (מי מאתנו לא משתמש ב-LINQ? זה ודאי יותר איטי מלולאה) אז צריך לבחור בצורה הגיונית מה עדיף, ואני לא צריך לתת ציונים מפורשים איזה פרמטר אני מעדיף. לך לפי השכל הישר. (אם יש לי קוד קצר כנגד קוד מאוד מסורבל אבל קצת יותר מהיר, אז אני אעדיף את הקוד הקצר, לעומת זאת אם יש לי קוד קצר איטי כנגד קוד יותר ארוך אבל יותר מהיר משמעותית אז אני יבחר את הקוד הארוך, ובפרט אם זה קוד שמתבצע הרבה פעמים, ולא רק פה ושם).אתה יודע מה, שורה תחתונה - אני מעוניין בקוד הכי קצר שאפשר.
-
תרגיל: עיגול מספר לפי מערך מפתחות@dovid אמר בתרגיל: עיגול מספר לפי מערך מפתחות:
אם הנקודה היא יעילות, יש פתרון יותר יעיל גם בלא ממויין.
זה השארתי לך לתרגל.
מעניין אותי אם תכתוב לנו את הפתרון מתי שהוא?
למה לא תחכים אותנו?! -
תרגיל: עיגול מספר לפי מערך מפתחות@dovid אמר בתרגיל: עיגול מספר לפי מערך מפתחות:
כל פעם אתה מוסיף ליעילות מילים שמטשטשות את התרגיל... קצר זה בקוד או בדרך שהמחשב יבצע?
יעיל: לחסוך במשאבים, לדוג' לא לבצע תרגילים כפולים (יש לי כמה פתרונות שנכתבים בשורה אחת אבל עם תרגילים שמתבצעים פעמיים)
קצר: קוד הכי קצר שאפשר.
-
תרגיל: עיגול מספר לפי מערך מפתחות@dovid אמר בתרגיל: עיגול מספר לפי מערך מפתחות:
אם הנקודה היא יעילות, יש פתרון יותר יעיל גם בלא ממויין.
מה הפתרון? אני ישמח לראות.
אם הנקודה היא יצירתיות שמופיעה בדבריך לסירוגין, אני לא יודע על מדד מוסכם לעניין אז קשה לדון מה הכי יצירתי.
הנקודה היא היעילות (הכי יעיל והכי קצר) והדרך להגיע לזה זה עם יצירתיות.
-
תרגיל: עיגול מספר לפי מערך מפתחותשלום לכולם.
אני עובד על מחשב שלא מחובר לאינטרנט, כך שלא כל שאלה אני ישר מחפש ב-stack.
כשעלה לי הצורך בתרגיל הזה ניסיתי לחשוב איך לעשות את, בהתחלה חשבתי על לולאה או פונקציה שתעשה את זה, אבל תוך כדי החשיבה צצו לי בראש כמה רעיונות לבצע את זה בשורה אחת, חלקם היו קצת לא יעילים, אז לכן פתחתי פה נושא במחשבה שאולי יש פה משהו שימצא פתרון יצירתי לתרגיל.כל זה היה לפני שפתחתי את גוגל.
אחרי שפתחתי את גוגל ראיתי הרבה פתרונות לתרגיל וזה עכשיו הופך את הנושא ללא רלוונטי, כי כבר כל הפתרונות היצירתיים נמצאים שם (לא יודע, אולי משהו פה ימצא רעיון יותר יצירתי).בכל אופן לפני שראיתי ב-stack זה הפתרון הכי יעיל שמצאתי:
int[] keys = Enumerable.Range(1, 9).Select(v => v * 100).ToArray(); // 100 200 300 ... int input = 673; int rounded = keys.MinBy(key => Math.Max(key - input, input - key));
הסבר: אני עובר על כל המספרים ולוקח את המקסימום מבין שני החישובים הבאים: קלט - מפתח, מפתח - קלט, תמיד אחד מהם יהיה מספר חיובי והשני שלילי, אז אני לוקח את המקסימום שזה המספר החיובי, ומחפש כזה מספר שהוא הכי נמוך, שזה אומר שהוא הכי קרוב למספר מפתח כלשהו.
אחר כך ראיתי ב-stack אפשרות יותר יצירתית:
int rounded = keys.MinBy(key => Math.Abs(key - input));
זה אותו רעיון אבל זה משתמש בפונקציה שהופכת את המספר השלילי לחיובי.
הפתרון הזה עובד על גם על מספרים לא ממוינים.
יכול להיות שבמספרים ממוינים תהיה דרך יותר יצירתית (בטוח שיש), אז אתם מוזמנים לנסות (בלי לפתוח גוגל!).יש לציין שהפתרון שלי הוא רק בשפות של NET., אבל בטוח יש דרכים יצירתיות גם בשפות אחרות. אז אתם גם מוזמנים לנסות (כמובן בלי גוגל).