سؤال

يقوم شريك موقعنا بإجراء مكالمة إلى خدمة ويب تتضمن معلمة تسمى الرمز المميز. الرمز المميز هو نتيجة تجزئة MD5 من رقمين، ويساعدنا على مصادقة المستخدم باستخدام نظام شركائنا. يسأل شريكنا المستخدم عن سلسلتين، تسلسلهم، يديرهم من خلال MD5، ثم يستدعي خدمة الويب الخاصة بنا. نتيجة MD5 هي الرمز المميز، ويتم إرسالها إلينا كسلسلة.

نقوم بتخزين الرموز السارية المباشرة في DB - نظرا لأننا نستخدم SQL Server لحساب الرموز في نهايتنا، إلا أن SQL بدا أنها أسعد تخزين الرموز المميزة كأداة فارغية، والتي هي النتيجة الأصلية لحساب MD5.

لدينا قطعتين من التعليمات البرمجية التي تحاول القيام بنفس الشيء - قم بتشغيل استعلام محدد يسحب قيمة استنادا إلى الرمز المميز. يستخدم المرء استعلام ديناميكي (وهو مشكلة)، لكنه يعمل. تحاول الآخر أن يفعل الشيء نفسه في الأزياء المعلمة (أكثر أمانا)، لا يعمل - لا يمكنه تحديد موقع الرمز المميز.

إليك المحاولتان المتنافسان. أولا، النسخة المعلمة التي تفشل:

byteArrayToken = System.Text.UnicodeEncoding.Unicode.GetBytes(stringToken)
scSelectThing.CommandText = "select thing from tokenstable where token=@token"
Dim param As SqlParameter = scSelectThing.Parameters.Add("@token", SqlDbType.VarBinary)
param.Value = byteArrayToken
lbOutput2.Text = scSelectThing.ExecuteScalar()

وثانيا، إصدار سلسلة الاستعلام الديناميكي الذي يعمل:

Dim scSelectThing As New SqlCommand
 scSelectThing.CommandText = "select thing from tokenstable where token=convert(varbinary, " + stringToken + " )"
lbOutput2.Text = scSelectThing.ExecuteScalar()

عندما ندير Profiler SQL، هذا هو ما يتم تنفيذه بالفعل مقابل DB:

exec sp_executesql N'select thing from tokenstable where token=@token',N'@token varbinary(68)',@token=0x3000780046003800380034004100450036003400430038003300440033004100380034003800460046004300380038004200390034003400330043004200370042004600

هذا لا يبدو صحيحا بالنسبة لي، يبدو كما لو أننا نفعل شيئا يقود شيئا ما في المكدس للقيام بالتحويل الخطأ في مكان ما.

أي أفكار ماذا سيكون ذلك؟ من الواضح أنه غير مقبول لإطلاقه مع استفسار ديناميكي هناك.

تعديل:

السلسلة هي نتيجة التجزئة MD5. لجعلها تعمل في محلل الاستعلام نقوم بذلك:

select * from tokenstable where 
token=convert(varbinary, 0xF664AE32C83D3A848FFC88B9443CB7BF )

لاحظ عدم وجود علامات الاقتباس، إذا اقتباسنا فشل الاستعلام. الحقل الذي نقارنه هو Varbinary، حيث قام SQL Server بتخزين نتائج حسابات MD5 في نهايتنا.

هل كانت مفيدة؟

المحلول

من المحتمل أن تكون مشكلتك من المحتمل أن تكون التحويلات الثنائية السلسلة تستخدم ترميزات مختلفة. جرب استخدام System.Text.Encoding.ASCII بدلاً من Unicode ومعرفة ما إذا كان هذا يفعل الحيلة لك. تخميني هو ذلك convert() ينظر إلى سلسلة الخاص بك ليكون varchar بدلا من nvarchar ويستخدم ASCII بدلا من Unicode للحصول على تحويل السلسلة> الثنائي.

تعديل

أيضا، هل هذه السلسلة تعادل ثنائي حقيقي للتجزئة، أم أنها تمثيل سداسي عشري؟

تحرير 2.

ثم مشكلتك هي أنك تمر بالتمثيل الثنائي للتمثيل السداسي عشري لبياناتك الثنائية. أن مربكة بما فيه الكفاية؟

تحتاج فقط إلى تحويل عرافة string إلى أ byte صفيف قبل إضافته كقيمة للمعلمة الخاصة بك. يمكنك القيام بذلك مع التعليمات البرمجية التالية، مأخوذة من الإجابة إلى هذا السؤال (وترجم إلى vb.net):

Public Shared Function StringToByteArray(ByVal hex As String) As Byte()
    Dim NumberChars As Integer = hex.Length

    Dim bytes(NumberChars / 2) As Byte

    For i As Integer = 0 To NumberChars - 1 Step 2
        bytes(i / 2) = Convert.ToByte(hex.Substring(i, 2), 16)
    Next

    Return bytes
End Function

لذلك سوف تبدو الكود الخاص بك شيء مثل هذا ...

byteArrayToken = StringToByteArray(stringToken)
scSelectThing.CommandText = "select thing from tokenstable where token=@token"
Dim param As SqlParameter = scSelectThing.Parameters.Add("@token", SqlDbType.VarBinary)
param.Value = byteArrayToken
lbOutput2.Text = scSelectThing.ExecuteScalar()
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top