Skip to content

Instantly share code, notes, and snippets.

@valentinvieriu
Last active December 19, 2024 14:41
Show Gist options
  • Save valentinvieriu/1d03d272bb5fb8a96fe0b6eb6babba63 to your computer and use it in GitHub Desktop.
Save valentinvieriu/1d03d272bb5fb8a96fe0b6eb6babba63 to your computer and use it in GitHub Desktop.
I use this script to generate Eurojackpot numbers for https://www.lotto-bayern.de/
// https://lotterycodex.com/eurojackpot-550/
// Generate a unique ticket number
const ticketNo = [...Array(7).keys()].map((i) => Math.floor(cryptoRandom() * 9)).join('');
const numberOfTickets = 12;
const drawings = [5]; // 5 - Friday; 4 - Wednesday ; 8 - Both
// Initialize the data object to be sent to the server
let data = {
"type": "JS",
"game": "EUROJACKPOT",
"subGame": "NORMAL",
ticketNo,
"drawings": [numberOfTickets],
"duration": 1,
drawings,
"price": 2,
"fee": 0.5,
"predate": null,
"additionalLotteries": null,
"subscription": null,
"cardNo": null,
"cardTemplateNo": null,
"basketIndex": null,
"subscriptionNo": null,
"extraRaffle": null,
"mainPrognosises": {
"EUROJACKPOT": []
}
};
// Fetch the historical statistics and generate tickets
(async () => {
// Fetch the statistics
let statsData;
try {
const statsResponse = await fetch('https://www.lotto-bayern.de/getEurojackpotStatisticsCounts?sorting=number', {
headers: {
'Accept': 'application/json, text/plain, */*',
},
});
if (!statsResponse.ok) {
throw new Error('Failed to fetch statistics');
}
statsData = await statsResponse.json();
if (!statsData.numbers || !statsData.additionalNumbers) {
throw new Error('Invalid statistics data');
}
} catch (error) {
console.error('Error fetching statistics:', error);
return;
}
// Generate tickets using the statistics and alternating logic
for (let index = 0; index < numberOfTickets; index++) {
const mainNumbers = generateNumbersWithAlternatingLogic(5, statsData.numbers, 50);
const euroNumbers = generateNumbersWithAlternatingLogic(2, statsData.additionalNumbers, 12);
data.mainPrognosises.EUROJACKPOT.push({
betModeNo: 4001,
prognosises: mainNumbers,
additionalPrognosises: euroNumbers,
fieldIndex: index
});
}
console.log('Generated data:', data);
// Send requests to the server
await fetch("https://www.lotto-bayern.de/deleteTicketFromSession?game=EUROJACKPOT&subgame=NORMAL", {
"headers": {
"accept": "application/json, text/plain, */*",
"content-type": "application/json;charset=UTF-8"
},
"method": "POST"
}).then(response => {
console.log(`deleteTicketFromSession: ${response.status}`);
});
await fetch("https://www.lotto-bayern.de/saveTicketInSession", {
"headers": {
"accept": "application/json, text/plain, */*",
"content-type": "application/json;charset=UTF-8"
},
"body": `{\"data\":\"${encodeURIComponent(JSON.stringify(data))}"}`,
"method": "POST"
}).then(response => {
console.log(`saveTicketInSession: ${response.status}`);
});
})();
/**
* Generates numbers based on historical statistics and alternating odd/even and high/low logic.
* @param {number} count - Number of numbers to generate.
* @param {Array} statsArray - Array of number statistics.
* @param {number} maxNumber - The maximum number in the range.
* @returns {Array} - An array of generated numbers.
*/
function generateNumbersWithAlternatingLogic(count, statsArray, maxNumber) {
// Adjust counts and calculate probabilities
const adjustedStats = statsArray.map(item => ({
number: item.number,
adjustedValue: Math.sqrt(item.value),
}));
// Categorize numbers into Odd/Even and Low/High
const categories = {
oddLow: [],
evenLow: [],
oddHigh: [],
evenHigh: [],
};
const midpoint = Math.floor(maxNumber / 2);
adjustedStats.forEach(item => {
const isOdd = item.number % 2 !== 0;
const isLow = item.number <= midpoint;
let categoryName;
if (isOdd && isLow) categoryName = 'oddLow';
else if (!isOdd && isLow) categoryName = 'evenLow';
else if (isOdd && !isLow) categoryName = 'oddHigh';
else categoryName = 'evenHigh';
categories[categoryName].push(item);
});
// Normalize probabilities within each category
for (const category in categories) {
const totalAdjustedValue = categories[category].reduce((sum, item) => sum + item.adjustedValue, 0);
categories[category] = categories[category].map(item => ({
number: item.number,
probability: item.adjustedValue / totalAdjustedValue,
}));
}
// Define the desired sequence of categories (alternating odd/even and high/low)
const sequence = ['oddLow', 'evenHigh', 'evenLow', 'oddHigh']; // Adjust as needed
let sequenceIndex = 0;
const selectedNumbers = new Set();
// Add debugging
console.log('Starting number generation...');
console.log('Categories:', categories);
while (selectedNumbers.size < count) {
const categoryName = sequence[sequenceIndex % sequence.length];
const categoryNumbers = categories[categoryName];
if (categoryNumbers && categoryNumbers.length > 0) {
const number = selectWeightedRandomNumber(categoryNumbers);
if (!selectedNumbers.has(number)) {
selectedNumbers.add(number);
console.log(`Selected number ${number} from category ${categoryName}`);
} else {
console.log(`Number ${number} already selected, retrying...`);
}
} else {
console.log(`Category ${categoryName} is empty, skipping...`);
}
sequenceIndex++;
}
return Array.from(selectedNumbers).sort((a, b) => a - b);
}
/**
* Selects a number from a category based on weighted probabilities.
* @param {Array} categoryNumbers - Array of numbers with their probabilities.
* @returns {number} - The selected number.
*/
function selectWeightedRandomNumber(categoryNumbers) {
// Compute cumulative probabilities
let cumulativeSum = 0;
const cumulativeProbabilities = categoryNumbers.map(item => {
cumulativeSum += item.probability;
return {
number: item.number,
cumulativeProbability: cumulativeSum,
};
});
// Generate a random number between 0 and cumulativeSum
const rand = Math.random() * cumulativeSum;
// Select the number based on cumulative probabilities
for (const item of cumulativeProbabilities) {
if (rand <= item.cumulativeProbability) {
return item.number;
}
}
// Fallback in case of rounding errors
return categoryNumbers[categoryNumbers.length - 1].number;
}
/**
* Generates a cryptographically secure random number between 0 and 1.
* @returns {number} - A random number between 0 and 1.
*/
function cryptoRandom() {
const typedArray = new Uint8Array(1);
const randomValue = crypto.getRandomValues(typedArray)[0];
const randomFloat = randomValue / 255; // Divide by 255 to get a number between 0 and 1
return randomFloat;
}
@gentrificationzolaz
Copy link

gentrificationzolaz commented Dec 19, 2024

If you want to improve the script or make it more versatile, you can add features such as saving previous numbers or preventing repetitions. I saw how it was implemented by https://zodiac-casinos.at/ on this site, and it works well. Additionally, if you are using a service like Lotto Bayern to play, make sure your script complies with their format and rules so you don't have any issues entering the numbers.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment