function returns empty string even though it shouldn't in golang - string

I'm having a strange issue.
I have a package named tools in which I have various files with tools for my main package, one of them generates a pseudorandom string that should contain uppercase, lowercase, numerical and certain special characters, to make sure I don't get a string that misses some of the types I did some validations and yet, i seem to miss something because I get an error every now and then
This is my main file:
package main
import (
"../tools"
"fmt"
"strings"
)
const lower = "abcdefghizklmnopqrstuvwxyz"
const upper = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
const numrical= "0123456789"
const special = "!#$^*"
func main (){
for i :=0; i<10; i++ {
str := tools.GenSpecial(15)
fmt.Println(str, validate(str))
}
}
func haslower (s string) bool {
return strings.ContainsAny(s,lower)
}
func hasupper (s string) bool {
return strings.ContainsAny(s,upper)
}
func hasnumrical (s string) bool {
return strings.ContainsAny(s,numrical)
}
func hasspecial (s string) bool {
return strings.ContainsAny(s,special)
}
func validate (s string) bool {
return haslower(s) && hasupper(s) && hasnumrical(s) && hasspecial(s)
}
and this is the relevant parts from my tools file:
package tools
import (
"math/rand"
"time"
"strings"
)
const alphanum =
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
const alphabet = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
const specialchars =
"abcdefghijklmnopqrstuwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!#$^*"
const lower = "abcdefghizklmnopqrstuvwxyz"
const upper = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
const numrical= "0123456789"
const special = "!#$^*"
func randomize() {
rand.Seed(time.Now().UnixNano())
}
func GenSpecial(n int) string { //function to generate a psuedorandom
alphabetical string with special characters
rstring := make([]byte, n)
for i := range rstring {
randomize()
rstring[i] = specialchars[rand.Intn(len(specialchars))]
}
if validate(string(rstring))&& string(rstring)!=""{
return string(rstring)
} else {
GenSpecial(n)
}
return "abc"
}
func haslower (s string) bool {
return strings.ContainsAny(s,lower)
}
func hasupper (s string) bool {
return strings.ContainsAny(s,upper)
}
func hasnumrical (s string) bool {
return strings.ContainsAny(s,numrical)
}
func hasspecial (s string) bool {
return strings.ContainsAny(s,special)
}
func validate (s string) bool {
return haslower(s) && hasupper(s) && hasnumrical(s) && hasspecial(s)
}
When I run my main file, i get some values that return the "abc" value, and I don't understand how or why.
Any ideas?

You are missing a return statement in your else case. If validate returns false, you call GenSpecial and then it returns "abc".
You want to say:
if validate(string(rstring))&& string(rstring)!=""{
return string(rstring)
} else {
return GenSpecial(n) // return here!
}

Related

How to remove string pattern and all the string behind that pattern?

For Example :
package main
import "fmt"
func main() {
pattern := "helloworld."
myString := "foo.bar.helloworld.qwerty.zxc.helloworld.asd"
fmt.Println(removeFromPattern(pattern, myString))
}
func removeFromPattern(p, ms string) string {
// I confused here (in efficient way)
}
Wanted output :
qwerty.zxc.helloworld.asd
How do I get that wanted output, also how to remove the first pattern and all the strings behind that pattern from myString ?
1- Using _, after, _ = strings.Cut(ms, p), try this:
func removeFromPattern(p, ms string) (after string) {
_, after, _ = strings.Cut(ms, p) // before and after sep.
return
}
Which uses strings.Index :
// Cut slices s around the first instance of sep,
// returning the text before and after sep.
// The found result reports whether sep appears in s.
// If sep does not appear in s, cut returns s, "", false.
func Cut(s, sep string) (before, after string, found bool) {
if i := Index(s, sep); i >= 0 {
return s[:i], s[i+len(sep):], true
}
return s, "", false
}
2- Using strings.Index, try this:
func removeFromPattern(p, ms string) string {
i := strings.Index(ms, p)
if i == -1 {
return ""
}
return ms[i+len(p):]
}
3- Using strings.Split, try this:
func removeFromPattern(p, ms string) string {
a := strings.Split(ms, p)
if len(a) != 2 {
return ""
}
return a[1]
}
4- Using regexp, try this
func removeFromPattern(p, ms string) string {
a := regexp.MustCompile(p).FindStringSubmatch(ms)
if len(a) < 2 {
return ""
}
return a[1]
}
strings.Split is enough
func main() {
pattern := "helloworld."
myString := "foo.bar.helloworld.qwerty.zxc"
res := removeFromPattern(pattern, myString)
fmt.Println(res)
}
func removeFromPattern(p, ms string) string {
parts := strings.Split(ms, p)
if len(parts) > 1 {
return parts[1]
}
return ""
}
func removeFromPattern(p, ms string) string {
return strings.ReplaceAll(ms, p, "")
}
func main() {
pattern := "helloworld."
myString := "foo.bar.helloworld.qwerty.zxc"
res := removeFromPattern(pattern, myString)
fmt.Println(res)
}

How to check if string contains both uppercase and lowercase characters

I need to validate password entered by user and check if the password contains at least one uppercase and one lowercase char in Dart.
I wrote this String extension:
extension StringValidators on String {
bool containsUppercase() {
// What code should be here?
}
bool containsLowercase() {
// What code should be here?
}
}
And use it like this:
final text = passwordTextController.text;
final isValid = text.containsUppercase() && text.containsLowercase();
Is there any regexp for this purpose? Or it should be plain algorithm? Please help me to find out the elegant way. Thanks!
Minimum 1 Upper case,
Minimum 1 lowercase,
Minimum 1 Numeric Number,
Minimum 1 Special Character,
Common Allow Character ( ! # # $ & * ~ )
bool validateStructure(String value){
String pattern = r'^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[!##\$&*~]).{8,}$';
RegExp regExp = new RegExp(pattern);
return regExp.hasMatch(value);
}
extension StringValidators on String {
bool get containsUppercase => contains(RegExp(r'[A-Z]'));
bool get containsLowercase => contains(RegExp(r'[a-z]'));
}
For only minimum 1 upper and minimum 1 Lower only, you could use this RegEx:
RegExp regEx = new RegExp(r"(?=.*[a-z])(?=.*[A-Z])\w+");
String a = "aBc";
String b = "abc";
String c = "ABC";
print("a => " + regEx.hasMatch(a).toString());
print("b => " + regEx.hasMatch(b).toString());
print("c => " + regEx.hasMatch(c).toString());
Expected Result:
I/flutter (10220): a => true
I/flutter (10220): b => false
I/flutter (10220): c => false
Reusable
extension StringValidators on String {
meetsPasswordRequirements() {
RegExp regEx = new RegExp(r"(?=.*[a-z])(?=.*[A-Z])\w+");
return regEx.hasMatch(this);
}
}
Use
final isValid = text.meetsPasswordRequirements();
void main() {
solve("coDE");
}
String solve(String s) {
// your code here
List _a = s.split("");
String _b = "";
List _x = [];
List _y = [];
for(var i in _a){
if(i.toString() == i.toString().toUpperCase()){
_x.add(i);
}else{
_y.add(i);
}
}
if(_x.length == _y.length){
_b = _a.join().toLowerCase();
}else if(_x.length > _y.length){
_b = _a.join().toUpperCase();
}else if(_x.length < _y.length){
_b = _a.join().toLowerCase();
}
return "$_b";
}
OR
String solve2(String str) {
return RegExp(r'[A-Z]').allMatches(str).length >
RegExp(r'[a-z]').allMatches(str).length
? str.toUpperCase()
: str.toLowerCase();
}

How to tokenize string with alphabetical and numerical values

I have a string like "test123abc45alsdkfj", I want my scanner to behave such that it read "test" first, then 123, then "abc", then 45, then "alsdkfj". Kinda like stringstream in C++, is there a way to do this? Thanks!
I think there is a simple way like this, hope it will help you
package main
import (
"fmt"
"strings"
"text/scanner"
)
func isDigit(c byte) bool {
if c >= 48 && c <= 57 {
return true
}
return false
}
func main() {
const src = `test123abc45alsdkfj`
var s scanner.Scanner
s.Init(strings.NewReader(src))
for tok := s.Scan(); tok != scanner.EOF; tok = s.Scan() {
chars := s.TokenText()
temp := string(chars[0])
for i := range chars {
if i > 0 {
if isDigit(chars[i]) != isDigit(chars[i-1]) {
fmt.Println(temp)
temp = string(chars[i])
} else {
temp += string(chars[i])
}
}
}
}
}
and output will be
test
123
abc
45

How to check if a string is all upper or lower case in Go?

What is an easy way in Golang to check if all characters in a string are upper case or lower case?
Also, how to handle a case where the string has punctuation?
See these examples:
package main
import (
"fmt"
"unicode"
)
func main() {
s := "UPPERCASE"
fmt.Println(s.IsUpper()) // Should print true
s = "lowercase"
fmt.Println(s.IsUpper()) // Should print false
s = "lowercase"
fmt.Println(s.IsLower()) // Should print true
s = "I'M YELLING AT YOU!"
fmt.Println(s.IsUpper()) // Should print true
}
Note: s.IsUpper() and s.IsLower() doesn't really exist, but would be nice to find an equivalent.
You can of course compare the upper and lower cased strings in their entirety, or you can short-circuit the comparisons on the first failure, which would be more efficient when comparing long strings.
func IsUpper(s string) bool {
for _, r := range s {
if !unicode.IsUpper(r) && unicode.IsLetter(r) {
return false
}
}
return true
}
func IsLower(s string) bool {
for _, r := range s {
if !unicode.IsLower(r) && unicode.IsLetter(r) {
return false
}
}
return true
}
One solution is to use strings.ToUpper()/ToLower() and compare with the original string. This works for the punctuation case as well.
Here's the solution:
package main
import (
"fmt"
"strings"
)
func main() {
s := "UPPERCASE"
fmt.Println(strings.ToUpper(s) == s)
s = "lowercase"
fmt.Println(strings.ToUpper(s) == s)
s = "lowercase"
fmt.Println(strings.ToLower(s) == s)
s = "I'M YELLING AT YOU!"
fmt.Println(strings.ToUpper(s) == s)
}
A unicode.{IsUpper, Lower} and B strings.{ToUpper, Lower} both good
For the data composed of single bytes, A will be better than B
If the data byte is unsure then B is better than A: for example 中文a1
package main
import (
"strings"
"testing"
"unicode"
)
func IsUpperU(s string) bool {
for _, r := range s {
if !unicode.IsUpper(r) && unicode.IsLetter(r) {
return false
}
}
return true
}
func IsUpper(s string) bool {
return strings.ToUpper(s) == s
}
func IsLowerU(s string) bool {
for _, r := range s {
if !unicode.IsLower(r) && unicode.IsLetter(r) {
return false
}
}
return true
}
func IsLower(s string) bool {
return strings.ToLower(s) == s
}
func TestIsUpper(t *testing.T) {
for _, d := range []struct {
actual bool
expected bool
}{
{IsUpperU("中文A1"), false}, // be careful!
{IsUpper("中文A1"), true},
{IsUpper("中文a1"), false},
{IsUpperU("中文a1"), false},
} {
if d.actual != d.expected {
t.Fatal()
}
}
}
func TestIsLower(t *testing.T) {
for idx, d := range []struct {
actual bool
expected bool
}{
{IsLowerU("中文a1"), false}, // be careful!
{IsLower("中文a1"), true},
{IsLower("中文A1"), false},
{IsLowerU("中文A1"), false},
} {
if d.actual != d.expected {
t.Fatal(idx)
}
}
}
go playground
No need for unicode (For English letters only):
func IsUpper(s string) bool {
for _, charNumber := range s {
if charNumber > 90 || charNumber < 65 {
return false
}
}
return true
}
func IsLower(s string) bool {
for _, charNumber := range s {
if charNumber > 122 || charNumber < 97 {
return false
}
}
return true
}

Converting to Char/String from Ascii Int in Swift

I'm trying to convert the integer representation of an ascii character back into a string.
string += (char) int;
In other languages like Java (the example here) I can just cast the integer into a char. Swift obviously does not know these and I'm guessing using the all powerful NSString somehow will be able to do the trick.
It may not be as clean as Java, but you can do it like this:
var string = ""
string.append(Character(UnicodeScalar(50)))
You can also modify the syntax to look more similar if you like:
//extend Character so it can created from an int literal
extension Character: IntegerLiteralConvertible {
public static func convertFromIntegerLiteral(value: IntegerLiteralType) -> Character {
return Character(UnicodeScalar(value))
}
}
//append a character to string with += operator
func += (inout left: String, right: Character) {
left.append(right)
}
var string = ""
string += (50 as Character)
Or using dasblinkenlight's method:
func += (inout left: String, right: Int) {
left += "\(UnicodeScalar(right))"
}
var string = ""
string += 50
Here's a production-ready solution in Swift 3:
extension String {
init(unicodeScalar: UnicodeScalar) {
self.init(Character(unicodeScalar))
}
init?(unicodeCodepoint: Int) {
if let unicodeScalar = UnicodeScalar(unicodeCodepoint) {
self.init(unicodeScalar: unicodeScalar)
} else {
return nil
}
}
static func +(lhs: String, rhs: Int) -> String {
return lhs + String(unicodeCodepoint: rhs)!
}
static func +=(lhs: inout String, rhs: Int) {
lhs = lhs + rhs
}
}
Usage:
let a = String(unicodeCodepoint: 42) // "*"
var b = a + 126 // "*~"
b += 33 // "*~!"
Note that this works with all ASCII and Unicode codepoints, so you can do this:
var emoji = String(unicodeCodepoint: 0x1F469)! // "👩"
emoji += 0x200D // "👩‍"
emoji += 0x1F4BB // "👩‍💻"
As a personal note, I wouldn't use this in my code. I would have expected ":" + 40 to become ":40", not ":(". If you prefer the second one where 40 becomes "(", then this should work well for you :)
If you want only String characters from A... you can use this func:
func characterFromInt(index : Int) -> String {
let startingValue = Int(("A" as UnicodeScalar).value)
var characterString = ""
characterString.append(Character(UnicodeScalar(startingValue + index)))
return characterString
}

Resources