Yazılım | Programlama C++ Rastgele Parola Üretimi (Unhandled exception hatası [Integer division by zero])

25 Eyl 2012
211
1
Sakarya
Merhaba,
C++ ile rastgele parola üreten static bir class yazdım. Fakat bir sorunla karşılaştım. İnternette biraz aradım, fakat çözüme ulaşamadım. Yardımcı olabilirseniz sevinirim.
Kod:
C++:
#include <iostream>
#include <vector>
#include <algorithm>
#include <numeric>
#include <random>

class RandomPasswordGenerator
{
public:
    static std::string GenerateRandomPassword(int PasswordLength, bool IncludeSpecialCharacters)
    {
        std::string LCASE = "abcdefghijklmnopqrstuvwxyz";
        std::string UCASE = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
        std::string NUM = "0123456789";
        std::string SPEC = "/*-+!#$&?_=@{}";

        std::vector<std::vector<char>> charGroups;

        if (IncludeSpecialCharacters)
        {
            charGroups = {
            std::vector<char>(LCASE.begin(), LCASE.end()),
            std::vector<char>(UCASE.begin(), UCASE.end()),
            std::vector<char>(NUM.begin(), NUM.end()),
            std::vector<char>(SPEC.begin(), SPEC.end())
            };
        }
        else
        {
            charGroups = {
            std::vector<char>(LCASE.begin(), LCASE.end()),
            std::vector<char>(UCASE.begin(), UCASE.end()),
            std::vector<char>(NUM.begin(), NUM.end())
            };
        }

        std::vector<int> charsLeftInGroup(charGroups.size());
        std::iota(charsLeftInGroup.begin(), charsLeftInGroup.end(), 0);

        std::vector<int> leftGroupsOrder(charsLeftInGroup);

        std::random_device rd;
        std::mt19937 rng(rd());

        std::shuffle(leftGroupsOrder.begin(), leftGroupsOrder.end(), rng);

        std::vector<char> password(PasswordLength);
        int nextCharIdx, nextGroupIdx, nextLeftGroupsOrderIdx, lastCharIdx, lastLeftGroupsOrderIdx = static_cast<int>(leftGroupsOrder.size()) - 1;

        for (int i = 0; i < PasswordLength; i++)
        {
            if (lastLeftGroupsOrderIdx == 0)
            {
                nextLeftGroupsOrderIdx = 0;
            }
            else
            {
                nextLeftGroupsOrderIdx = rng() % lastLeftGroupsOrderIdx;
            }

            nextGroupIdx = leftGroupsOrder[nextLeftGroupsOrderIdx];
            lastCharIdx = charsLeftInGroup[nextGroupIdx] - 1;

            if (lastCharIdx == 0)
            {
                nextCharIdx = 0;
            }
            else
            {
                nextCharIdx = rng() % (lastCharIdx +1); // hatanın oluştuğu satır
            }

            password[i] = charGroups[nextGroupIdx][nextCharIdx];

            if (lastCharIdx == 0)
            {
                charsLeftInGroup[nextGroupIdx] = static_cast<int>(charGroups[nextGroupIdx].size());
            }
            else
            {
                if (lastCharIdx != nextCharIdx)
                {
                    std::swap(charGroups[nextGroupIdx][nextCharIdx], charGroups[nextGroupIdx][lastCharIdx]);
                }
                charsLeftInGroup[nextGroupIdx]--;
            }

            if (lastLeftGroupsOrderIdx == 0)
            {
                lastLeftGroupsOrderIdx = static_cast<int>(leftGroupsOrder.size()) - 1;
            }
            else
            {
                if (lastLeftGroupsOrderIdx != nextLeftGroupsOrderIdx)
                {
                    std::swap(leftGroupsOrder[nextLeftGroupsOrderIdx], leftGroupsOrder[lastLeftGroupsOrderIdx]);
                }
                lastLeftGroupsOrderIdx--;
            }
        }
        return std::string(password.begin(), password.end());
    }
};

int main()
{
    std::string password = RandomPasswordGenerator::GenerateRandomPassword(12, false);
    std::cout << "Generated Password: " << password << std::endl;

    std::cin.get();
    return 0;
}

Hata:
Exception thrown at 0x00007FF78A655A4E in App1.exe: 0xC0000094: Integer division by zero.
Unhandled exception at 0x00007FF78A655A4E in App1.exe: 0xC0000094: Integer division by zero.

İnternette bulduğum çözüm önerilerinide nextCharIdx = rng() % (lastCharIdx +1); kodundaki lastCharIdx +1 bölümünü silmem söyleniyordu. Yani nextCharIdx = rng() % (lastCharIdx); olarak değiştirmem gerektiği.
Bende kodu nextCharIdx = rng() % (lastCharIdx); olarak değiştirim. Derlemede bir hata oluşmadı. Fakat programı çalıştırdığım zaman Runtime Error verdi.
Bu hatayı nasıl çözebilirim?

Genel Bilgiler:
Sistem: Windows 10 x64
C++ Versiyonu: C++20
Derleyici: x64 MSVC v19.38
 
Çözüm
F
lastCharIdx in -1 e eşit olabileceği durumu göz önünden kaçırmışsınız, bunu düzeltmek için ekran görüntüsünde görmüş olduğunuz if yapısının altına bu kodu yerleştirmeniz yeterli olacaktır. "lol397q.PNG"
C++:
if (lastCharIdx == -1)
            {
                lastCharIdx = 0;
                nextCharIdx = 0;
            }

lastCharIdx in -1 e eşit olma sebebi yukarıda yapmış olduğunuz işlemlerden dolayı kaynaklanıyor. charsLeftInGroup vektöründe indekslemiş olduğunuz nextGroupIdx değeri sıfıra eşit olabilir, ve bu değerden -1 i çıkarırsanız lastCharIdx -1 e eşit oluyor.

lastCharIdx in -1 e eşit olabileceği durumu göz önünden kaçırmışsınız, bunu düzeltmek için ekran görüntüsünde görmüş olduğunuz if yapısının altına bu kodu...

Suppressor

Request Uzmanı
16 Kas 2022
1,206
716
always, everywhere
Tam emin değilim ama denermisin ?

C++:
#include <iostream>
#include <vector>
#include <algorithm>
#include <numeric>
#include <random>

class RandomPasswordGenerator
{
public:
    static std::string GenerateRandomPassword(int PasswordLength, bool IncludeSpecialCharacters)
    {
        if (PasswordLength <= 0 || (!IncludeSpecialCharacters && PasswordLength < 3))
        {
            std::cerr << "Invalid password configuration. Password length should be greater than 0, and if special characters are excluded, the length should be at least 3." << std::endl;
            return ""; // Return an empty string for an invalid configuration
        }

        std::string LCASE = "abcdefghijklmnopqrstuvwxyz";
        std::string UCASE = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
        std::string NUM = "0123456789";
        std::string SPEC = "/*-+!#$&?_=@{}";

        std::vector<std::vector<char>> charGroups;

        if (IncludeSpecialCharacters)
        {
            charGroups = {
                std::vector<char>(LCASE.begin(), LCASE.end()),
                std::vector<char>(UCASE.begin(), UCASE.end()),
                std::vector<char>(NUM.begin(), NUM.end()),
                std::vector<char>(SPEC.begin(), SPEC.end())
            };
        }
        else
        {
            charGroups = {
                std::vector<char>(LCASE.begin(), LCASE.end()),
                std::vector<char>(UCASE.begin(), UCASE.end()),
                std::vector<char>(NUM.begin(), NUM.end())
            };
        }

        std::vector<int> charsLeftInGroup(charGroups.size());
        std::iota(charsLeftInGroup.begin(), charsLeftInGroup.end(), 0);

        std::vector<int> leftGroupsOrder(charsLeftInGroup);

        std::random_device rd;
        std::mt19937 rng(rd());

        std::shuffle(leftGroupsOrder.begin(), leftGroupsOrder.end(), rng);

        std::vector<char> password(PasswordLength);
        int nextCharIdx, nextGroupIdx, nextLeftGroupsOrderIdx, lastCharIdx, lastLeftGroupsOrderIdx = static_cast<int>(leftGroupsOrder.size()) - 1;

        for (int i = 0; i < PasswordLength; i++)
        {
            if (lastLeftGroupsOrderIdx == 0)
            {
                nextLeftGroupsOrderIdx = 0;
            }
            else
            {
                nextLeftGroupsOrderIdx = rng() % lastLeftGroupsOrderIdx;
            }

            nextGroupIdx = leftGroupsOrder[nextLeftGroupsOrderIdx];
            lastCharIdx = charsLeftInGroup[nextGroupIdx] - 1;

            if (lastCharIdx == 0)
            {
                nextCharIdx = 0;
            }
            else
            {
                nextCharIdx = rng() % (lastCharIdx + 1);
            }

            password[i] = charGroups[nextGroupIdx][nextCharIdx];

            if (lastCharIdx == 0)
            {
                charsLeftInGroup[nextGroupIdx] = static_cast<int>(charGroups[nextGroupIdx].size());
            }
            else
            {
                if (lastCharIdx != nextCharIdx)
                {
                    std::swap(charGroups[nextGroupIdx][nextCharIdx], charGroups[nextGroupIdx][lastCharIdx]);
                }
                charsLeftInGroup[nextGroupIdx]--;
            }

            if (lastLeftGroupsOrderIdx == 0)
            {
                lastLeftGroupsOrderIdx = static_cast<int>(leftGroupsOrder.size()) - 1;
            }
            else
            {
                if (lastLeftGroupsOrderIdx != nextLeftGroupsOrderIdx)
                {
                    std::swap(leftGroupsOrder[nextLeftGroupsOrderIdx], leftGroupsOrder[lastLeftGroupsOrderIdx]);
                }
                lastLeftGroupsOrderIdx--;
            }
        }

        return std::string(password.begin(), password.end());
    }
};

int main()
{
    int passwordLength = 12;
    bool includeSpecialCharacters = false;

    std::string password = RandomPasswordGenerator::GenerateRandomPassword(passwordLength, includeSpecialCharacters);

    if (!password.empty())
    {
        std::cout << "Generated Password: " << password << std::endl;
    }

    std::cin.get();
    return 0;
}
 
25 Eyl 2012
211
1
Sakarya
Tam emin değilim ama denermisin ?

C++:
#include <iostream>
#include <vector>
#include <algorithm>
#include <numeric>
#include <random>

class RandomPasswordGenerator
{
public:
    static std::string GenerateRandomPassword(int PasswordLength, bool IncludeSpecialCharacters)
    {
        if (PasswordLength <= 0 || (!IncludeSpecialCharacters && PasswordLength < 3))
        {
            std::cerr << "Invalid password configuration. Password length should be greater than 0, and if special characters are excluded, the length should be at least 3." << std::endl;
            return ""; // Return an empty string for an invalid configuration
        }

        std::string LCASE = "abcdefghijklmnopqrstuvwxyz";
        std::string UCASE = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
        std::string NUM = "0123456789";
        std::string SPEC = "/*-+!#$&?_=@{}";

        std::vector<std::vector<char>> charGroups;

        if (IncludeSpecialCharacters)
        {
            charGroups = {
                std::vector<char>(LCASE.begin(), LCASE.end()),
                std::vector<char>(UCASE.begin(), UCASE.end()),
                std::vector<char>(NUM.begin(), NUM.end()),
                std::vector<char>(SPEC.begin(), SPEC.end())
            };
        }
        else
        {
            charGroups = {
                std::vector<char>(LCASE.begin(), LCASE.end()),
                std::vector<char>(UCASE.begin(), UCASE.end()),
                std::vector<char>(NUM.begin(), NUM.end())
            };
        }

        std::vector<int> charsLeftInGroup(charGroups.size());
        std::iota(charsLeftInGroup.begin(), charsLeftInGroup.end(), 0);

        std::vector<int> leftGroupsOrder(charsLeftInGroup);

        std::random_device rd;
        std::mt19937 rng(rd());

        std::shuffle(leftGroupsOrder.begin(), leftGroupsOrder.end(), rng);

        std::vector<char> password(PasswordLength);
        int nextCharIdx, nextGroupIdx, nextLeftGroupsOrderIdx, lastCharIdx, lastLeftGroupsOrderIdx = static_cast<int>(leftGroupsOrder.size()) - 1;

        for (int i = 0; i < PasswordLength; i++)
        {
            if (lastLeftGroupsOrderIdx == 0)
            {
                nextLeftGroupsOrderIdx = 0;
            }
            else
            {
                nextLeftGroupsOrderIdx = rng() % lastLeftGroupsOrderIdx;
            }

            nextGroupIdx = leftGroupsOrder[nextLeftGroupsOrderIdx];
            lastCharIdx = charsLeftInGroup[nextGroupIdx] - 1;

            if (lastCharIdx == 0)
            {
                nextCharIdx = 0;
            }
            else
            {
                nextCharIdx = rng() % (lastCharIdx + 1);
            }

            password[i] = charGroups[nextGroupIdx][nextCharIdx];

            if (lastCharIdx == 0)
            {
                charsLeftInGroup[nextGroupIdx] = static_cast<int>(charGroups[nextGroupIdx].size());
            }
            else
            {
                if (lastCharIdx != nextCharIdx)
                {
                    std::swap(charGroups[nextGroupIdx][nextCharIdx], charGroups[nextGroupIdx][lastCharIdx]);
                }
                charsLeftInGroup[nextGroupIdx]--;
            }

            if (lastLeftGroupsOrderIdx == 0)
            {
                lastLeftGroupsOrderIdx = static_cast<int>(leftGroupsOrder.size()) - 1;
            }
            else
            {
                if (lastLeftGroupsOrderIdx != nextLeftGroupsOrderIdx)
                {
                    std::swap(leftGroupsOrder[nextLeftGroupsOrderIdx], leftGroupsOrder[lastLeftGroupsOrderIdx]);
                }
                lastLeftGroupsOrderIdx--;
            }
        }

        return std::string(password.begin(), password.end());
    }
};

int main()
{
    int passwordLength = 12;
    bool includeSpecialCharacters = false;

    std::string password = RandomPasswordGenerator::GenerateRandomPassword(passwordLength, includeSpecialCharacters);

    if (!password.empty())
    {
        std::cout << "Generated Password: " << password << std::endl;
    }

    std::cin.get();
    return 0;
}
Teşekkür ederim. Denedim. Fakat yine aynı satırda, aynı hatayı alıyorum.
 

Bunjo

Uzman üye
14 Ara 2020
1,592
1,896
I Won
Merhaba,
C++ ile rastgele parola üreten static bir class yazdım. Fakat bir sorunla karşılaştım. İnternette biraz aradım, fakat çözüme ulaşamadım. Yardımcı olabilirseniz sevinirim.
Kod:
C++:
#include <iostream>
#include <vector>
#include <algorithm>
#include <numeric>
#include <random>

class RandomPasswordGenerator
{
public:
    static std::string GenerateRandomPassword(int PasswordLength, bool IncludeSpecialCharacters)
    {
        std::string LCASE = "abcdefghijklmnopqrstuvwxyz";
        std::string UCASE = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
        std::string NUM = "0123456789";
        std::string SPEC = "/*-+!#$&?_=@{}";

        std::vector<std::vector<char>> charGroups;

        if (IncludeSpecialCharacters)
        {
            charGroups = {
            std::vector<char>(LCASE.begin(), LCASE.end()),
            std::vector<char>(UCASE.begin(), UCASE.end()),
            std::vector<char>(NUM.begin(), NUM.end()),
            std::vector<char>(SPEC.begin(), SPEC.end())
            };
        }
        else
        {
            charGroups = {
            std::vector<char>(LCASE.begin(), LCASE.end()),
            std::vector<char>(UCASE.begin(), UCASE.end()),
            std::vector<char>(NUM.begin(), NUM.end())
            };
        }

        std::vector<int> charsLeftInGroup(charGroups.size());
        std::iota(charsLeftInGroup.begin(), charsLeftInGroup.end(), 0);

        std::vector<int> leftGroupsOrder(charsLeftInGroup);

        std::random_device rd;
        std::mt19937 rng(rd());

        std::shuffle(leftGroupsOrder.begin(), leftGroupsOrder.end(), rng);

        std::vector<char> password(PasswordLength);
        int nextCharIdx, nextGroupIdx, nextLeftGroupsOrderIdx, lastCharIdx, lastLeftGroupsOrderIdx = static_cast<int>(leftGroupsOrder.size()) - 1;

        for (int i = 0; i < PasswordLength; i++)
        {
            if (lastLeftGroupsOrderIdx == 0)
            {
                nextLeftGroupsOrderIdx = 0;
            }
            else
            {
                nextLeftGroupsOrderIdx = rng() % lastLeftGroupsOrderIdx;
            }

            nextGroupIdx = leftGroupsOrder[nextLeftGroupsOrderIdx];
            lastCharIdx = charsLeftInGroup[nextGroupIdx] - 1;

            if (lastCharIdx == 0)
            {
                nextCharIdx = 0;
            }
            else
            {
                nextCharIdx = rng() % (lastCharIdx +1); // hatanın oluştuğu satır
            }

            password[i] = charGroups[nextGroupIdx][nextCharIdx];

            if (lastCharIdx == 0)
            {
                charsLeftInGroup[nextGroupIdx] = static_cast<int>(charGroups[nextGroupIdx].size());
            }
            else
            {
                if (lastCharIdx != nextCharIdx)
                {
                    std::swap(charGroups[nextGroupIdx][nextCharIdx], charGroups[nextGroupIdx][lastCharIdx]);
                }
                charsLeftInGroup[nextGroupIdx]--;
            }

            if (lastLeftGroupsOrderIdx == 0)
            {
                lastLeftGroupsOrderIdx = static_cast<int>(leftGroupsOrder.size()) - 1;
            }
            else
            {
                if (lastLeftGroupsOrderIdx != nextLeftGroupsOrderIdx)
                {
                    std::swap(leftGroupsOrder[nextLeftGroupsOrderIdx], leftGroupsOrder[lastLeftGroupsOrderIdx]);
                }
                lastLeftGroupsOrderIdx--;
            }
        }
        return std::string(password.begin(), password.end());
    }
};

int main()
{
    std::string password = RandomPasswordGenerator::GenerateRandomPassword(12, false);
    std::cout << "Generated Password: " << password << std::endl;

    std::cin.get();
    return 0;
}

Hata:
Exception thrown at 0x00007FF78A655A4E in App1.exe: 0xC0000094: Integer division by zero.
Unhandled exception at 0x00007FF78A655A4E in App1.exe: 0xC0000094: Integer division by zero.

İnternette bulduğum çözüm önerilerinide nextCharIdx = rng() % (lastCharIdx +1); kodundaki lastCharIdx +1 bölümünü silmem söyleniyordu. Yani nextCharIdx = rng() % (lastCharIdx); olarak değiştirmem gerektiği.
Bende kodu nextCharIdx = rng() % (lastCharIdx); olarak değiştirim. Derlemede bir hata oluşmadı. Fakat programı çalıştırdığım zaman Runtime Error verdi.
Bu hatayı nasıl çözebilirim?

Genel Bilgiler:
Sistem: Windows 10 x64
C++ Versiyonu: C++20
Derleyici: x64 MSVC v19.38
C++:
nextCharIdx = (lastCharIdx == 0) ? 0 : rng() % (lastCharIdx + 1);

Bir de böyle deneyiniz.
 
F

Floppaging

Ziyaretçi
lastCharIdx in -1 e eşit olabileceği durumu göz önünden kaçırmışsınız, bunu düzeltmek için ekran görüntüsünde görmüş olduğunuz if yapısının altına bu kodu yerleştirmeniz yeterli olacaktır. "lol397q.PNG"
C++:
if (lastCharIdx == -1)
            {
                lastCharIdx = 0;
                nextCharIdx = 0;
            }

lastCharIdx in -1 e eşit olma sebebi yukarıda yapmış olduğunuz işlemlerden dolayı kaynaklanıyor. charsLeftInGroup vektöründe indekslemiş olduğunuz nextGroupIdx değeri sıfıra eşit olabilir, ve bu değerden -1 i çıkarırsanız lastCharIdx -1 e eşit oluyor.

lastCharIdx in -1 e eşit olabileceği durumu göz önünden kaçırmışsınız, bunu düzeltmek için ekran görüntüsünde görmüş olduğunuz if yapısının altına bu kodu yerleştirmeniz yeterli olacaktır. "lol397q.PNG"

C++:
if (lastCharIdx == -1)

            {

                lastCharIdx = 0;

                nextCharIdx = 0;

            }

lastCharIdx in -1 e eşit olma sebebi yukarıda yapmış olduğunuz işlemlerden dolayı kaynaklanıyor. charsLeftInGroup vektöründe indekslemiş olduğunuz nextGroupIdx değeri sıfıra eşit olabilir, ve bu değerden -1 i çıkarırsanız lastCharIdx -1 e eşit oluyor.
 
Çözüm
25 Eyl 2012
211
1
Sakarya
lastCharIdx in -1 e eşit olabileceği durumu göz önünden kaçırmışsınız, bunu düzeltmek için ekran görüntüsünde görmüş olduğunuz if yapısının altına bu kodu yerleştirmeniz yeterli olacaktır. "lol397q.PNG"
C++:
if (lastCharIdx == -1)
            {
                lastCharIdx = 0;
                nextCharIdx = 0;
            }

lastCharIdx in -1 e eşit olma sebebi yukarıda yapmış olduğunuz işlemlerden dolayı kaynaklanıyor. charsLeftInGroup vektöründe indekslemiş olduğunuz nextGroupIdx değeri sıfıra eşit olabilir, ve bu değerden -1 i çıkarırsanız lastCharIdx -1 e eşit oluyor.
Teşekkür ederim. Sorun çözüldü. Eline sağlık.
 
Üst

Turkhackteam.org internet sitesi 5651 sayılı kanun’un 2. maddesinin 1. fıkrasının m) bendi ile aynı kanunun 5. maddesi kapsamında "Yer Sağlayıcı" konumundadır. İçerikler ön onay olmaksızın tamamen kullanıcılar tarafından oluşturulmaktadır. Turkhackteam.org; Yer sağlayıcı olarak, kullanıcılar tarafından oluşturulan içeriği ya da hukuka aykırı paylaşımı kontrol etmekle ya da araştırmakla yükümlü değildir. Türkhackteam saldırı timleri Türk sitelerine hiçbir zararlı faaliyette bulunmaz. Türkhackteam üyelerinin yaptığı bireysel hack faaliyetlerinden Türkhackteam sorumlu değildir. Sitelerinize Türkhackteam ismi kullanılarak hack faaliyetinde bulunulursa, site-sunucu erişim loglarından bu faaliyeti gerçekleştiren ip adresini tespit edip diğer kanıtlarla birlikte savcılığa suç duyurusunda bulununuz.