Meneroka Kekuatan Kata Laluan dan Pengesahan Nombor dalam Perl and Go

Barbara Streisand
Lepaskan: 2024-09-24 06:22:32
asal
983 orang telah melayarinya

Exploring Password Strength and Number Validation in Perl and Go

In this article, I will tackle two challenges from the Perl Weekly Challenge #287: strengthening weak passwords and validating numbers. I will provide solutions for both tasks, showcasing implementations in Perl and Go.

Table of Contents

  1. Strengthening Weak Passwords
  2. Validating Numbers
  3. Conclusion

Strengthening Weak Passwords

The first task is to determine the minimum number of changes needed to make a password strong. The criteria for a strong password are:

  1. It has at least 6 characters.
  2. It contains at least one lowercase letter, one uppercase letter, and one digit.
  3. It does not contain three consecutive identical characters.

Examples

  • Input: "a" → Output: 5
  • Input: "aB2" → Output: 3
  • Input: "PaaSW0rd" → Output: 0
  • Input: "Paaasw0rd" → Output: 1
  • Input: "aaaaa" → Output: 2

The Solution

Perl Implementation

#!/usr/bin/perl
use strict;
use warnings;
use List::Util 'max';

# Function to count groups of three or more repeating characters
sub count_repeats {
    my ($str) = @_;
    my $repeats = 0;

    # Find repeating characters and count the required changes
    while ($str =~ /(.)\1{2,}/g) {
        $repeats += int(length($&) / 3);
    }

    return $repeats;
}

# Function to calculate the minimum steps to create a strong password
sub minimum_steps_to_strong_password {
    my ($str) = @_;
    my $length = length($str);

    # Check if the password contains the required character types
    my $has_lower = $str =~ /[a-z]/;
    my $has_upper = $str =~ /[A-Z]/;
    my $has_digit = $str =~ /\d/;

    # Calculate the number of types needed
    my $types_needed = !$has_lower + !$has_upper + !$has_digit;
    my $repeats = count_repeats($str);

    # Return the minimum steps based on the length of the password
    return ($length < 6) ? max(6 - $length, $types_needed) : $types_needed + $repeats;
}

1;
Salin selepas log masuk

Tests for the Perl Implementation

use strict;
use warnings;
use Test::More;
require "./ch-1.pl";

my @tests = (
    ["a", 5],
    ["aB2", 3],
    ["PaaSW0rd", 0],
    ["Paaasw0rd", 1],
    ["aaaaa", 2],
);

foreach my $test (@tests) {
    my ($input, $expected) = @$test;
    my $result = minimum_steps_to_strong_password($input);
    is($result, $expected, "Input: '$input'");
}

done_testing();
Salin selepas log masuk

Go Implementation

package main

import (
    "regexp"
)

func countRepeats(password string) int {
    repeats := 0
    count := 1

    for i := 1; i < len(password); i++ {
        if password[i] == password[i-1] {
            count++
        } else {
            repeats += count / 3
            count = 1
        }
    }
    repeats += count / 3
    return repeats
}

func minimumStepsToStrongPassword(password string) int {
    length := len(password)

    // Use regex to check for character types
    hasLower := regexp.MustCompile(`[a-z]`).MatchString(password)
    hasUpper := regexp.MustCompile(`[A-Z]`).MatchString(password)
    hasDigit := regexp.MustCompile(`\d`).MatchString(password)

    // Calculate the number of types needed
    typesNeeded := boolToInt(!hasLower) + boolToInt(!hasUpper) + boolToInt(!hasDigit)

    repeats := countRepeats(password)

    // Return the minimum steps based on the length of the password
    if length < 6 {
        return max(6-length, typesNeeded)
    }
    return typesNeeded + repeats
}


func boolToInt(b bool) int {
    if b {
        return 1
    }
    return 0
}

func max(a, b int) int {
    if a > b {
        return a
    }
    return b
}
Salin selepas log masuk

Tests for the Go Implementation

package main

import (
    "testing"
)

func TestMinimumStepsToStrongPassword(t *testing.T) {
    tests := []struct {
        password string
        expected int
    }{
        {"a", 5},
        {"aB2", 3},
        {"PaaSW0rd", 0},
        {"Paaasw0rd", 1},
        {"aaaaa", 2},
    }

    for _, test := range tests {
        result := minimumStepsToStrongPassword(test.password)
        if result != test.expected {
            t.Errorf("For password '%s', expected %d but got %d", test.password, test.expected, result)
        }
    }
}
Salin selepas log masuk

Validating Numbers

The second task involves validating numbers. The goal is to determine whether a given string represents a valid number. The criteria for a valid number are:

  1. An integer optionally followed by exponential notation.
  2. A decimal number optionally followed by exponential notation.
  3. An integer may optionally have a sign (- or +) followed by digits.

Examples

  • Input: "1" → Output: true
  • Input: "a" → Output: false
  • Input: "." → Output: false
  • Input: "1.2e4.2" → Output: false
  • Input: "-1." → Output: true
  • Input: "+1E-8" → Output: true
  • Input: ".44" → Output: true

The Solution

Perl Implementation

#!/usr/bin/perl
use strict;
use warnings;

sub is_valid_number {
    my ($str) = @_;

    # Regex for valid numbers
    my $regex = qr{
        ^            # Start of the string
        [+-]?        # Optional sign
        (?:          # Start of the number group
            \d+      # Integer: at least one digit
            (?:      # Start of the optional decimal part
                \.   # Decimal point
                \d*  # Followed by zero or more digits
            )?       # Group is optional
            |        # or
            \.       # Just a decimal point
            \d+      # Followed by one or more digits
        )            # End of the number group
        (?:          # Start of the optional exponent group
            [eE]     # 'e' or 'E'
            [+-]?    # Optional sign
            \d+      # Followed by one or more digits
        )?           # Exponent is optional
        $            # End of the string
    }x;

    # Return 1 for valid, 0 for invalid
    return $str =~ $regex ? 1 : 0;
}

1;
Salin selepas log masuk

Tests for the Perl Implementation

#!/usr/bin/perl
use strict;
use warnings;
use Test::More;

require './ch-2.pl';

# Define test cases
my @test_cases = (
    ["1", 1, 'Valid integer'],
    ["a", 0, 'Invalid input'],
    [".", 0, 'Single dot'],
    ["1.2e4.2", 0, 'Invalid exponent'],
    ["-1.", 1, 'Valid decimal'],
    ["+1E-8", 1, 'Valid scientific notation'],
    [".44", 1, 'Valid decimal starting with dot'],
);

# Loop through test cases and run tests
foreach my $case (@test_cases) {
    my $result = is_valid_number($case->[0]);
    is($result, $case->[1], $case->[2]);
}

done_testing();
Salin selepas log masuk

Go Implementation

package main

import (
    "regexp"
)

// isValidNumber checks if the given string is a valid number.
func isValidNumber(str string) bool {
    regex := `^[+-]?((\d+(\.\d*)?)|(\.\d+))([eE][+-]?\d+)?$`
    matched, _ := regexp.MatchString(regex, str)
    return matched
}
Salin selepas log masuk

Tests for the Go Implementation

package main

import (
    "testing"
)

func TestIsValidNumber(t *testing.T) {
    testCases := []struct {
        input    string
        expected bool
    }{
        {"1", true},
        {"a", false},
        {".", false},
        {"1.2e4.2", false},
        {"-1.", true},
        {"+1E-8", true},
        {".44", true},
    }

    for _, tc := range testCases {
        result := isValidNumber(tc.input)
        if result != tc.expected {
            t.Errorf("isValidNumber(%q) = %v; expected %v", tc.input, result, tc.expected)
        }
    }
}
Salin selepas log masuk

Conclusion

These solutions provide effective methods for evaluating password strength and validating the correctness of numbers. The complete code for both tasks is available on GitHub.

Atas ialah kandungan terperinci Meneroka Kekuatan Kata Laluan dan Pengesahan Nombor dalam Perl and Go. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

sumber:dev.to
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Artikel terbaru oleh pengarang
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan