xor בג'אווה

קונדסבא

New member
xor בג'אווה

האם יש דרך פשוטה בג'אווה (פשוטה יותר אשר לממש בעצמי פונקציה) לעשות פעולת xor בין שני סטרינגים של Hex? כלומר:

String a="68656c6c6f20776f726c64"
String b="68656c6c6f206e6f6f6221"
result= "00000000000019001d0e45"
 

selalerer

New member
long זה 8. תחתוך אותו לשניים.

תכניס כל חצי ל-long בעזרת Long.decode, תעשה xor ותמיר חזרה ל-string בעזרת Long.parseString.
 

קונדסבא

New member
ואם אני רוצה לטפל בסטרינג שמייצג בינארי?

נגיד:
string s: "100000010100010110101"

סתם זרקתי עכשיו מספרים רק כדי להבהיר מה כוונתי.
דרך אגב פעולת הxor נחשבת נדירה? אחרת אני לא מבין איך אין מימוש שלם שמטפל בכל העסק...
 

selalerer

New member
xor ל-stringים זה בד"כ לא דבר מובנה בשפה.

יש אני מניח ספריות לטפל בזה, אבל זה באמת קצת טיפשי שאתה עושה פעולה שהמעבד יודע לעשות במהירות מדהימה על טיפוס שהמעבד לא יודע לעשות אותו עליה (string) במקום על הטיפוס שטבעי לעשות את הפעולה הזאת עליו (int, long).
 

selalerer

New member
תשתמש ב-parseString להמיר מה-string ל-long

ובחזרה תשתמש ב toBinaryString
 

קונדסבא

New member
למה אני לא מצליח להמיר

קודם כל הבנתי שבשביל להשתמש בLong.decode אני חייב להוסיף לתחילת המחרוזת 0x. זה מצליח לי בכמה סטרינגים אבל משום מה בסטרינג הזה זה נכשל:
0x83d04e008a7897ee
אני מקבל אקספשן
java.lang.NumberFormatException: For input string: "83d04e008a7897ee"
 

BravoMan

Active member
המספר הזה גדול מידי כדי להיכנס ל-long

וזו הסיבה.

אני חושב שאתה ניגש לבעיה שלך בצורה שגויה:
אם זה תרגיל לימודים, בטח ציפו שתממש לבד, או לפחות תפרק את המחרוזת בית בית.

אם זה לפרויקט אמתי, כנראה שיש דרך הרבה יותר טובה להשיג את מה שאתה באמת צריך להשיג, אבל אם לא תספר לנו מה זה, לעולם לא נדע.

בכל מקרה, קח בחשבון שהיות ו-Java סובל מחוסר בטיפוסים unsigned, את צריך לעשות המרות כאלה לאט ובזהירות!
 

קונדסבא

New member
זה לקורס מכוון שאני עושה בקריפטוגרפיה

הדגש הוא לא על פעולת הxor...ונראה שמי שעושה את התרגיל הזה בפייתון עושה אותו צ'יק צ'ק....אני לא יודע פייתון ואני ממש ממש מתקשה בהתאמת המשתנים שלי...חלק מהפונקציות מקבלות byte[] חלק סטרינג...ובנוסף גם יש את כל הקטע הזה של ההמרה לhex ומ-hex וזה פשוט הופך להיות סיוט.
זאת ממש לא כוונת המשורר...
 

Javali

New member
צריך להגיד כל דבר פעמיים?

תשתמש ב-BigInteger. זה עושה תרגום ממחרוזות ואל מחרוזות. זה עןשה את כל פעולות החשבון הבסיסיות. זה עושה פעולות על ביטים. זה מה שמשתמשים בשביל הצפנות. (לפחות בסיסיות.) אתה יכול, כמובן, לוותר על זה ולהמציא את הגלגל מחדש. אבל מישהו כבר עשה את העבודה בשבילך.
 

קונדסבא

New member
תודה!

כמו שכתבתי בהודעה לnocdod פשוט חיכתי שאולי תהיה תשובה אחרת מאשר הbigInteger כי כבר היה לי ניסיון כושל איתו.
אני אנסה שוב...תודה!
 

nocgod

New member
סגולה של כל מתכנת היא לחפש באינטרנט

תשובות לשאלות שכבר נשאלו...
http://stackoverflow.com/questions/9840675/xor-hex-string-in-java-of-different-length

הפיתרון: עבור כל מחרוזת בhex עוברים תו-תו ועושים לו xor עם התו המקביל לו את התוצאה מחברים בחזרה למערך תווים.
התווים בjava (במיוחד אם מדובר בunicode יכולים להיות בני 16bits) קצת יותר גדולים מתווים ב C לצורך העניין, לכן לא תמיד תוצאה של xor בין 2 תווים תיתן לך תו חוקי, לכן אולי כדאי
לשמור את התווים ב bytes כדי לשדר או לשמור...
 

קונדסבא

New member
חיפשתי באינטרנט

וגם הגעתי בדיוק להודעה שבקישור שלך, וניסיתי את BigInteger אבל משום מה זה לא עבד לי...איפשהו בין כל כל ההמרות התחלתי להסתבך ולקבל אקספשנים ותוצאות xor שגויות...
בגלל זה חיפשתי דרך פחות מגושמות לבצע את זה כדי למזער תקלות ולהתמקד בעיקר של התרגיל...
 

nocgod

New member
אז לא חיפשת טוב מה אני אגיד לך...

public static void main(String[] args)
{
String hexStr = "83d04e008a7897ee";

BigInteger bigInt = new BigInteger(hexStr, 16);

BigInteger bigInt2 = new BigInteger(hexStr, 16);

System.out.println("As integer: " + bigInt);
System.out.println("As hex: " + bigInt.toString(16));
System.out.println("As binary: " + bigInt.toString(2))
;
System.out.println("xor: " + bigInt.xor(bigInt2).toString(16) + " expected 0");
}
 
למעלה