CRYPT_GEN_RANDOM
एक "क्रिप्टोग्राफिक यादृच्छिक संख्या" वापस जाने के लिए दर्ज है।
यह 1
और 8000
के बीच एक लंबा पैरामीटर लेता है जो बाइट्स में वापस आने की संख्या की लंबाई है।
लंबाई < = 8 बाइट्स के लिए। इसे सीधे SQL Server integer types में से एक में डाला जा सकता है।
+-----------+------------------+---------+
| Data type | Range | Storage |
+-----------+------------------+---------+
| bigint | -2^63 to 2^63-1 | 8 Bytes |
| int | -2^31 to 2^31-1 | 4 Bytes |
| smallint | -2^15 to 2^15-1 | 2 Bytes |
| tinyint | 0 to 255 | 1 Byte |
+-----------+------------------+---------+
उनमें से तीन हस्ताक्षर किए गए पूर्णांक और एक हस्ताक्षरित हैं। निम्नलिखित प्रत्येक अपने संबंधित डेटाटाइप की पूरी श्रृंखला का उपयोग करेंगे।
SELECT
CAST(CRYPT_GEN_RANDOM(1) AS TINYINT),
CAST(CRYPT_GEN_RANDOM(2) AS SMALLINT),
CAST(CRYPT_GEN_RANDOM(4) AS INT),
CAST(CRYPT_GEN_RANDOM(8) AS BIGINT)
डाटाटाइप स्टोरेज की तुलना में कम मूल्य प्रदान करना भी संभव है।
SELECT CAST(CRYPT_GEN_RANDOM(3) AS INT)
इस मामले में केवल सकारात्मक संख्याएं वापस की जा सकती हैं। साइन बिट हमेशा 0 होगा क्योंकि अंतिम बाइट 0x00
के रूप में माना जाता है। उपरोक्त द्वारा वापस किए जा सकने वाले संभावित संख्याओं की सीमा 0
और POWER(2, 24) - 1
समावेशी के बीच है।
मान लीजिए कि 1 and 250
के बीच कुछ यादृच्छिक संख्या उत्पन्न करने की आवश्यकता है। यह ऐसा करने का
एक संभव तरीका होगा
SELECT (1 + CAST(CRYPT_GEN_RANDOM(1) AS TINYINT) % 250) AS X
INTO #T
FROM master..spt_values V1, master..spt_values
हालांकि इस पद्धति का एक समस्या है।
SELECT COUNT(*),X
FROM #T
GROUP BY X
ORDER BY X
पहले दस परिणामों की पंक्तियों क्योंकि वहाँ मापांक समारोह उत्पन्न कर सकते हैं कि करने के लिए दो संभावित आदानों हैं दूसरों के रूप में के रूप में नियमित रूप से दो बार उत्पन्न कर रहे हैं (इस मामले 1 -6
में)
+-------+----+
| Count | X |
+-------+----+
| 49437 | 1 |
| 49488 | 2 |
| 49659 | 3 |
| 49381 | 4 |
| 49430 | 5 |
| 49356 | 6 |
| 24914 | 7 |
| 24765 | 8 |
| 24513 | 9 |
| 24732 | 10 |
+-------+----+
लोअर नंबर दिए गए हैं उन परिणामों में से प्रत्येक।
एक संभव समाधान सभी नंबरों को निरस्त करने के लिए किया जाएगा> = 250
UPDATE #T
SET X = CASE
WHEN Random >= 250 THEN NULL
ELSE (1 + Random % 250)
END
FROM #T
CROSS APPLY (SELECT CAST(CRYPT_GEN_RANDOM(1) AS TINYINT)) CA (Random)
यह मेरा मशीन पर काम करने के लिए प्रकट होता है लेकिन यह शायद इसकी गारंटी नहीं है कि SQL सर्वर केवल समारोह एक बार दोनों संदर्भों को भर में Random
करने का मूल्यांकन करेंगे CASE
अभिव्यक्ति में। इसके अतिरिक्त यह NULL
पंक्तियों को ठीक करने के लिए दूसरी और बाद के पास की आवश्यकता की समस्या को छोड़ देता है जहां यादृच्छिक मान को त्याग दिया गया था।
एक स्केलर घोषित करना यूडीएफ उन दोनों मुद्दों को हल कर सकता है।
/*Work around as can't call CRYPT_GEN_RANDOM from a UDF directly*/
CREATE VIEW dbo.CRYPT_GEN_RANDOM1
AS
SELECT CAST(CRYPT_GEN_RANDOM(1) AS TINYINT) AS Random
go
CREATE FUNCTION GET_CRYPT_GEN_RANDOM1()
RETURNS TINYINT
AS
BEGIN
DECLARE @Result TINYINT
WHILE (@Result IS NULL OR @Result >= 250)
/*Not initialised or result to be discarded*/
SELECT @Result = Random FROM dbo.CRYPT_GEN_RANDOM1
RETURN @Result
END
और फिर
UPDATE #T
SET X = dbo.GET_CRYPT_GEN_RANDOM1()
वैकल्पिक रूप से और अधिक सीधे आगे की ओर एक बस
CAST(CRYPT_GEN_RANDOM(8) AS BIGINT) % 250
आधार पर इस्तेमाल कर सकते हैं कि bigint
की सीमा इतनी बड़ी है कि किसी भी पूर्वाग्रह की संभावना नगण्य हो जाएगा । 73,786,976,294,838,208 तरीके हैं जो 1
उत्पन्न किए जा सकते हैं और 73,786,976,294,838,206 249
उपर्युक्त क्वेरी से हो सकते हैं।
यदि यहां तक कि छोटे संभव पूर्वाग्रहों की अनुमति नहीं है तो आप पहले दिखाए गए अनुसार NOT BETWEEN -9223372036854775750 AND 9223372036854775749
किसी भी मूल्य को त्याग सकते हैं।
@ इंड्री क्या आप स्पष्ट कर सकते हैं कि आपको क्या कमी है? 'CRYPT_GEN_RANDOM' पूरी तरह से ठीक उत्तर की तरह दिखता है। – CodesInChaos
@CodesInChaos 'CRYPT_GEN_RANDOM' बिल्कुल संख्या उत्पन्न नहीं करता है .. बेशक आप उन्हें Int में परिवर्तित कर सकते हैं, लेकिन क्या लंबाई आवश्यक होगी? उदाहरण के लिए, यदि मुझे 8 अंकों की क्रिप्टोग्राफ़िक रूप से सुरक्षित संख्याएं उत्पन्न करने की आवश्यकता है, तो मैं 'CRYPT_GEN_RANDOM' का उपयोग कैसे कर सकता हूं? इसके अलावा, क्या वे अद्वितीय हैं? –
इसके अलावा मैं 'SQL' में सुरक्षित संख्याएं उत्पन्न करने के किसी भी अन्य तरीके के बारे में उत्सुक हूं। –