[RESOLVED] Problems having a function return two values
Hello, I'm having trouble with a function returning two values. Each value contains a string, how can I return these values and have each one of them be stored in one independent variable.
How can I do this? This is my code:
vb.net Code:
Public Shared Function SHA256StringHash(ByVal text As String, Optional ByVal salt As Boolean = False) As String
Try
Select Case salt
Case True
Dim textBytes As Byte() = _encoding.GetBytes(text)
Dim myrandom As New Random
Dim rng As New RNGCryptoServiceProvider
Dim randomSalt As Byte() = New Byte(myrandom.Next(4, 8)) {}
rng.GetNonZeroBytes(randomSalt)
Dim SaltedText_Byte As Byte() = New Byte((textBytes.Length + randomSalt.Length) - 1) {}
SaltedText_Byte = textBytes.Concat(randomSalt).ToArray
Dim SaltedHash As Byte() = hash.ComputeHash(SaltedText_Byte)
Return Convert.ToBase64String(SaltedHash) _
AndAlso Convert.ToBase64String(randomSalt)
Return Nothing
Case Else
Dim textBytes As Byte() = _encoding.GetBytes(text)
Dim textHash As Byte() = hash.ComputeHash(textBytes)
Return Convert.ToBase64String(textHash)
End Select
Catch ex As Exception
Return ex.Message
End Try
End Function
I'm trying to return the hashed text with the salt and the generated salt, how can I do this?
Thanks in advance!
Re: Problems having a function return two values
In general to return more than one value from a function you can either pass the variables to the function and declare them ByRef rather than ByVal....
OR...
create a structure that contains both values and return the structure.
kevin
Re: Problems having a function return two values
In this case I think I can't use ByRef because I'm only passing 1 variable to the function and I'm returning 2. If I were to go with option 2, how would I "get them"?
I have never used structures before, that's why I'm asking...
Re: Problems having a function return two values
Hi tassa,
kebo is correct, you can either use structure or, you can use class for returing the values.
Re: Problems having a function return two values
in most cases you can do it byref. Byref means you are passing a reference to the variable to the function... not simply the value of the variable. If the variable changes in the function, it also changes outside the function. If you do use byref, there is also no need for a function.. you can use a sub instead...
Code:
Dim var1
Dim var2
call mysub(var1,var2)
'now the returned vars are in var1 and var2
Private Sub mysub(ByVal var1, ByVal var2)
'do stuff
'assign the first return variable to var1
'assign the second to var2
End Sub
using a structure you would use something like this....
Code:
Private Structure MyDataStructure
Public var1 As Integer
Public var2 As Integer
End Structure
Dim myvars As MyDataStructure = MyFunction()
var1 = myvars.var1
var2 = myvars.var2
Private Function MyFunction() As MyDataStructure
'do some stuff
'to create the to things that need to be returned...
Dim ReturnStruct As MyDataStructure
ReturnStruct.var1 = 'the first variable to be returned
ReturnStruct.var2 = 'the second variable to be returned
Return ReturnStruct
End Function
kevin
Re: Problems having a function return two values
Re: [RESOLVED] Problems having a function return two values
First up, that method has a serious, SERIOUS problem. There's absolutely no way you should be returning an error message. If an exception is thrown in that method, how is the caller supposed to know it? As it is the caller would simply use the error message as though it was a valid result. Very, VERY bad! That method shouldn't be handling any exceptions at all. If an exception is thrown it should be up to the caller of that method to handle it and then it knows that an error occurred and it can decide what to do about it.
Secondly, why would you use a Select Case statement to test a Boolean value? The point of Select Case is that it can test multiple cases. If there are only two cases then you should just be using an If...Else statement.
As for the question, you should really be overloading that method and have one with two parameters and the other with one:
vb.net Code:
Public Shared Function SHA256StringHash(ByVal text As String, ByRef salt As String) As String
'...
End Function
Public Shared Function SHA256StringHash(ByVal text As String) As String
'...
End Function
In one you generate a salt and assign it to the parameter and in the other you don't. If there's common code then either one overload can call the other or else you can define a third method that does the common work.
Re: [RESOLVED] Problems having a function return two values
OK, I fixed the first point and the second point. I don't understand why I should be using two statements if I can do it in one.
Re: [RESOLVED] Problems having a function return two values
Quote:
Originally Posted by
tassa
OK, I fixed the first point and the second point. I don't understand why I should be using two statements if I can do it in one.
There's no rule that says one method is better than two. Clarity is important and in this case two methods is clearer than one. As far as the caller is concerned it makes no difference. As it stands you've got an optional parameter so the user can call the method with one argument or two. If they pass one then no salt is generated and if they pass two it is. The same goes for my code. The caller would use the same method name with one argument or two.
Your code simply won't pass back the generated salt as is. In order to do so you'd have to add a third parameter that would pass the salt back ByRef, but that would make no sense if the user specified False for generating salt so the code becomes nonsensical. Two methods is clearer and cleaner so you should use two methods, or three if appropriate.
Never let writing fewer methods be something you strive for. You write as many methods as are appropriate for the circumstances.
Re: [RESOLVED] Problems having a function return two values
It seems logical to write down two or more methods, however, in this case, I don't think it'll help me, since I'm not generating a salt value from a given string, I'm generating a random salt value (depending if the boolean value = true) and then returning the generated salt.
Nevertheless, I'm going to explore what you've recommended and see what happens.
Re: [RESOLVED] Problems having a function return two values
Quote:
Originally Posted by
tassa
It seems logical to write down two or more methods, however, in this case, I don't think it'll help me, since I'm not generating a salt value from a given string, I'm generating a random salt value (depending if the boolean value = true) and then returning the generated salt.
Nevertheless, I'm going to explore what you've recommended and see what happens.
Of course it will help. With two methods the user either passes a salt argument by reference or they don't. If they do then a value is generated and passed back:
vb.net Code:
Dim salt As Byte()
Dim hash As String = SHA256StringHash(someText, salt)
After that you've got the hash and the salt. If you don't want salt then you don't pass the second parameter:
vb.net Code:
Dim hash As String = SHA256StringHash(someText)
No salt argument is passed so no salt is generated and no salt is passed back. In this case it's the presence of the second argument, not its value, that decides whether salt is generated and used or not. Converting your original code would yield:
vb.net Code:
Public Overloads Shared Function SHA256StringHash(ByVal text As String, ByRef salt As Byte()) As String
Dim textBytes As Byte() = _encoding.GetBytes(text)
Dim myrandom As New Random
Dim rng As New RNGCryptoServiceProvider
salt = New Byte(myrandom.Next(4, 8)) {}
rng.GetNonZeroBytes(salt)
Dim SaltedText_Byte As Byte() = New Byte((textBytes.Length + salt.Length) - 1) {}
SaltedText_Byte = textBytes.Concat(salt).ToArray
Dim SaltedHash As Byte() = hash.ComputeHash(SaltedText_Byte)
Return Convert.ToBase64String(SaltedHash)
End Function
Public Overloads Shared Function SHA256StringHash(ByVal text As String) As String
Dim textBytes As Byte() = _encoding.GetBytes(text)
Dim textHash As Byte() = hash.ComputeHash(textBytes)
Return Convert.ToBase64String(textHash)
End Function
Re: [RESOLVED] Problems having a function return two values
Here's the three method version, although I haven't tested it:
vb.net Code:
Public Overloads Shared Function SHA256StringHash(ByVal text As String, ByRef salt As Byte()) As String
Dim textBytes As Byte() = _encoding.GetBytes(text)
Dim myrandom As New Random
Dim rng As New RNGCryptoServiceProvider
salt = New Byte(myrandom.Next(4, 8)) {}
rng.GetNonZeroBytes(salt)
Dim SaltedText_Byte As Byte() = New Byte((textBytes.Length + salt.Length) - 1) {}
SaltedText_Byte = textBytes.Concat(salt).ToArray
Return SHA256StringHash(SaltedText_Byte)
End Function
Public Overloads Shared Function SHA256StringHash(ByVal text As String) As String
Dim textBytes As Byte() = _encoding.GetBytes(text)
Return SHA256StringHash(textBytes)
End Function
Public Overloads Shared Function SHA256StringHash(ByVal data As Byte()) As String
Dim textHash As Byte() = hash.ComputeHash(data)
Return Convert.ToBase64String(textHash)
End Function
Re: [RESOLVED] Problems having a function return two values
WOW! It is clearer! Hadn't you showed me that modification, I wouldn't have been able to come up with something like that. That's something I'll keep in mind from now on!
Re: [RESOLVED] Problems having a function return two values
Why do you return like this:
Code:
Return SHA256StringHash(textBytes)
In the three method version?
Re: [RESOLVED] Problems having a function return two values
Quote:
Originally Posted by
tassa
Why do you return like this:
Code:
Return SHA256StringHash(textBytes)
In the three method version?
The first and second overloads both call the third overload to actually create the hash. The first two methods get the Bytes to be hashed and then the common functionality, i.e. hashing those Bytes, is performed in the third overload. Each of the first two overloads calls the third, pass it the data and returns the result.
Re: [RESOLVED] Problems having a function return two values
Ok, cool. Wow, thanks for your help! Really, really helpful :D!
Re: [RESOLVED] Problems having a function return two values
How would I return the salt? Should I create a structure and return the whole structure? I'm eager wanting to return the salt since I'm creating a class and I want to be able to get the generated salt and be able to save it or whatever.
EDIT:
Disregard my question. It was a dumb one, I blame my lack of sleep. Since it's ByRef the orignal value is "edited". So there's my answer ;).
EDIT 2:
In case anyone wants to know more about Overloads, it helped me understand what it is and does.
Re: [RESOLVED] Problems having a function return two values
Just in case you ever want to use a structure for this (I like using structures better), it would look like this. The function would return an instance of your structure, instead of a string directly.
The following function returns a structure with a Name, LastName and Age property; effectively returning three values:
vb.net Code:
Public Structure Person
Public Name As String
Public LastName As String
Public Age As Integer
End Structure
Public Function GetPerson() As Person
Dim p As New Person With {.Name = "Nick", _
.LastName = "Thissen", _
.Age = 20}
Return p
End Function
Private Sub SomeMethod()
'This is the method you call the function in
Dim p As Person = GetPerson()
MessageBox.Show(String.Format("{0} {1}, {2}", _
p.Name, _
p.LastName, _
p.Age))
End Sub
As you may see, structures behave more or less the same as classes (except, they are value types unlike classes)
Re: [RESOLVED] Problems having a function return two values
Quote:
Originally Posted by
NickThissen
Just in case you ever want to use a structure for this (I like using structures better), it would look like this. The function would return an instance of your structure, instead of a string directly.
The following function returns a structure with a Name, LastName and Age property; effectively returning three values:
vb.net Code:
Public Structure Person
Public Name As String
Public LastName As String
Public Age As Integer
End Structure
Public Function GetPerson() As Person
Dim p As New Person With {.Name = "Nick", _
.LastName = "Thissen", _
.Age = 20}
Return p
End Function
Private Sub SomeMethod()
'This is the method you call the function in
Dim p As Person = GetPerson()
MessageBox.Show(String.Format("{0} {1}, {2}", _
p.Name, _
p.LastName, _
p.Age))
End Sub
As you may see, structures behave more or less the same as classes (except, they are value types unlike classes)
I'm not a big fan of defining a type solely for the purpose of being returned by one method. If it has other uses then fair enough but I'd tend not to go with it here. Also, by using a ByRef parameter you allow the return type of the function to remain the same whether salt is added or not. You certainly could create a new type but I don't see it as the best option in this case.