|
|
Hi,
I am currently working on SHA256withRSA algorithm in Window Fomrs, C#. My main objective is to get signed signature of my encrypted SHA256withRSA string with my Custom Private Key String which I generated from an online tool. In order to do that, I came to know that it happens via RSACryptoServiceProvider . Now in order to complete my sign operation I have to get the RSAParameters of my private key. And when I trying it the only part that I am getting is Modulus and Exponent part of the string. But I want to extract all of the components (P, Q, DP, DQ, InverseQ, D).
So where I am stuck unable to do it for quite some time. this is my first time working with this encryption stuff. And not sure if I am following the right convention.
Thanks
|
|
|
|
|
With a "custom private key string", and "component extraction", and "first time working", I wouldn't trust you.
It was only in wine that he laid down no limit for himself, but he did not allow himself to be confused by it.
― Confucian Analects: Rules of Confucius about his food
|
|
|
|
|
Gerry Schmitz,
Thanks for replying. I totally understand your concern. But at first I was following this link[^] and trying to understand all of the procedures.
As for my project, I would be getting a private key from the client (by adding some sort of certificate - which I don't know much about just yet, but that thing is in the future). so after getting that key I have to sign it with my SHA256withRSA string. And that's all I have to do for now.
|
|
|
|
|
|
Hi All,
I am using Microsoft azure storage account class in C# to upload a file to storage account in C#.
Does anyone know how can i share the uploaded file with multiple users through C# code.
|
|
|
|
|
|
In the past, I did most of my work with parallel objects using Rx, but that was made a bit cumbersome in the recent project. So I was following the code from Brian Lagunas, I made some tweaks to it to see how it all worked.
using Prism.Mvvm;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace WpfAsynTaskAwait
{
public class MainViewModel:BindableBase
{
#region "ctor"
public MainViewModel()
{
Text = "1: Main UI thread on: " + Thread.CurrentThread.ManagedThreadId.ToString();
Task.Run(() => DoSomething(MethodCallback)).Await(CompletedCallback, ErrorCallback);
}
#endregion
async Task DoSomething(Action<string> methodCallback)
{
await Task.Delay(1500);
methodCallback?.Invoke("2: Task starts on thread: " + Thread.CurrentThread.ManagedThreadId.ToString());
await Task.Delay(1500);
methodCallback?.Invoke("3: Task runs on thread: " + Thread.CurrentThread.ManagedThreadId.ToString());
await Task.Delay(1500);
}
#region "Variables"
private string _text = "Default value";
public string Text
{
get { return _text; }
set
{
SetProperty(ref _text, value);
}
}
#endregion
#region "Callback methods"
private void CompletedCallback()
{
Text = "4: Method completed called from thread: " + Thread.CurrentThread.ManagedThreadId.ToString();
}
private void MethodCallback(string message)
{
Text = message + Environment.NewLine + "Task callback from thread: " + Thread.CurrentThread.ManagedThreadId.ToString();
}
private void ErrorCallback(Exception ex)
{
Text = ex.Message;
}
#endregion
}
public static class TaskExtensions
{
public async static void Await(this Task task, Action completedCallback, Action<Exception> errorCallback)
{
try
{
await task;
completedCallback?.Invoke();
}
catch (Exception ex)
{
errorCallback?.Invoke(ex);
}
}
}
}
I just found it rather confusing that the method MethodCallback was allowed to interact directly (update) via binding with a UI-bound element. And my DoSomething does not return a Task but still does not complain about the implementation. This just confuses me. Why am I allowed to interact via callbacks from a worker thread to a UI thread?
|
|
|
|
|
Aren't callbacks just executed on the main thread, instead of the invoking one?
> "Task callback from thread: " + Thread.CurrentThread.ManagedThreadId.ToString()
Aigt, Convert.ToString(Thread.CurrentThread.ManagedThreadId) to avoid a Null-exception. What did your logs say? And if updating directly, instead of binding, does it show the same result?
Bastard Programmer from Hell
"If you just follow the bacon Eddy, wherever it leads you, then you won't have to think about politics." -- Some Bell.
|
|
|
|
|
It's WPF stuff with PRISM, so I don't really have access to the textbox in the GUI directly. But it says that the application changes the property Text from the background thread. The text is thus updated on the UI via the binding and INotifiedPropertyChange interaction.
|
|
|
|
|
If you modify a bound property in your view model from a non-UI thread, WPF automatically marshals the UI update changes for that property to the UI thread. It works for all scalar types, but not collections. You have to create your own collection type that does the marshalling.
|
|
|
|
|
Thank you for the answer Dave.
So I modified the code in the MethodCallback and got exactly what you said :
This type of CollectionView does not support changes to its SourceCollection from a thread different from the Dispatcher thread.
Now I have some more research to go further.
The change in the code is just banal, Binding to a TextBox and Listview's itemssource directly will throw the exception:
public class MainViewModel:BindableBase
{
#region "ctor"
public MainViewModel()
{
Text = "1: Main UI thread on: " + Thread.CurrentThread.ManagedThreadId.ToString();
TextCollection.Add("1: Main UI thread on: " + Thread.CurrentThread.ManagedThreadId.ToString());
Task.Run(() => DoSomething(MethodCallback)).Await(CompletedCallback, ErrorCallback);
}
#endregion
async Task DoSomething(Action<string> methodCallback)
{
await Task.Delay(1500);
methodCallback?.Invoke("2: Task starts on thread: " + Thread.CurrentThread.ManagedThreadId.ToString());
TextCollection.Add("2,5: Task starts on thread: " + Thread.CurrentThread.ManagedThreadId.ToString());
await Task.Delay(1500);
methodCallback?.Invoke("3: Task runs on thread: " + Thread.CurrentThread.ManagedThreadId.ToString());
await Task.Delay(1500);
}
#region "Variables"
private ObservableCollection<string> _textCollection = new ObservableCollection<string>();
public ObservableCollection<string> TextCollection
{
get { return _textCollection; }
set { SetProperty(ref _textCollection, value); }
}
private string _text = "Default value";
public string Text
{
get { return _text; }
set
{
SetProperty(ref _text, value);
}
}
#endregion
#region "Callback methods"
private void CompletedCallback()
{
Text = "4: Method completed called from thread: " + Thread.CurrentThread.ManagedThreadId.ToString();
TextCollection.Add("4: Method completed called from thread: " + Thread.CurrentThread.ManagedThreadId.ToString());
}
private void MethodCallback(string message)
{
Text = message + Environment.NewLine + "Task callback from thread: " + Thread.CurrentThread.ManagedThreadId.ToString();
TextCollection.Add(message + Environment.NewLine + "Task callback from thread: " + Thread.CurrentThread.ManagedThreadId.ToString());
}
private void ErrorCallback(Exception ex)
{
Text = ex.Message;
}
#endregion
}
public static class TaskExtensions
{
public async static void Await(this Task task, Action completedCallback, Action<Exception> errorCallback)
{
try
{
await task;
completedCallback?.Invoke();
}
catch (Exception ex)
{
errorCallback?.Invoke(ex);
}
}
}
|
|
|
|
|
|
I like this. Not a lot of backbreaking coding work
Literally just added two lines of code and all works well.
private object _TextCollectionLock = new object();
public MainViewModel()
{
BindingOperations.EnableCollectionSynchronization(TextCollection, _TextCollectionLock);
...
}
|
|
|
|
|
|
Huh, I didn't know know about that.
That makes life a little easier.
|
|
|
|
|
I made an opc client in order to connect to Rockwell Rslinx. I used only OPCgroup.SyncRead and SyncWrite. Everything is working fine and I write and read tags from a Rockwell plc. To test the SyncWrite I used a sine wave and i see it correctly in the trend page of the plc. In addition when I press a button on the form I set a value until I keep the button pressed which return to zero when I release the button (let's say a pulse). That value is written in the PLC and I can check it in the trend the same. Then I read it back from the PLC in the form.
To do that I place the value of the sine wave in array[0] and the value of the pulse in array[1]. Then array is passed to the SyncWrite. So, as I said, here everything is OK.
Then I had to add a new functionality. This is a second order system (T(s) or second order filter).
I use the same array of course and now array[0] is the result of the filter and array[1] is again the pulse.
The pulse is read back from the PLC and is now the force perturbing the system. In order to switch from the sine wave calculation to the filtering I use a button that enable filtering or sine wave alternatively.
Here I got crazy because, when I switch to filter and press the button that generate the pulse to be read back from the plc, pulse does not arrive to the PLC. But the strangest thing is that within array[1] I see the value of the pulse at the moment when it should be sent to the PLC through the SyncWrite.
This I can see in debugging when I set the point of interrupt in the line with the SyncWrite here below
public static void Write_synchr(RSIOPC r)
{
try
{
DataToSend.SetValue(r.array_to_send, 1);
r.RSLinxOPCgroup_w.SyncWrite(1, ref r.SyncServerHandles_w, ref DataToSend, out SyncErrors2);
}
catch (Exception e)
{
MessageBox.Show(e.ToString(), "Error: ",
MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
I mean that interrupting at the line of the SyncWrite, inside DataToSend I see the correct value but it does not reach PLC.
Even stranger the fact that sometimes I saw it working, I do not know how, but not always. So I tried with some different ways to correct but nothing to do.
Then I made a lot of other test and here below is what I saw.
public float test_second_order_filter()
{
force[0] = ... the result of the SyncRead to read the value of the pulse ...
filter[0] = (float) (-(filter[2] * param_filter[2] / param_filter[0]) - (filter[1] * param_filter[1] / param_filter[0]) +
+(force[2] * param_force[2] / param_filter[0]) + (force[1] * param_force[1] / param_filter[0]) +
+(force[0] * param_force[0] / param_filter[0]));
filter[2] = filter[1];
filter[1] = filter[0];
force[2] = force[1];
force[1] = force[0];
return filter[0];
}
that is exactly what I have to do but the behaviour is what described in the introduction
Then I tried with a simplified version :
public float test_second_order_filter()
{
force[0] = ... the result of the SyncRead to read the value of the pulse ...
filter[0] = (float) (force[0] + filter[2]);
filter[2] = filter[1];
filter[1] = filter[0];
force[2] = force[1];
force[1] = force[0];
return filter[0];
}
(Formula here makes no sense) Again no way
Then I tried with this :
public float test_second_order_filter()
{
force[0] = ... the result of the SyncRead to read the value of the pulse ...
filter[0] = (float) (force[0] + 1 + filter[2]);
filter[2] = filter[1];
filter[1] = filter[0];
force[2] = force[1];
force[1] = force[0];
return filter[0];
}
(Formula here makes no sense) Something happens and when I press the button sometimes the pulse arrives to the PLC, I see the PLC trend moving. From the ....try ... catch error come about access violation in SyncWrite many times but code does not stop and continue doing something.
Then I tried with this :
public float test_second_order_filter()
{
force[0] = ... the result of the SyncRead to read the value of the pulse ...
filter[0] = (float) (force[0] + 0.005 + filter[2]);
filter[2] = filter[1];
filter[1] = filter[0];
force[2] = force[1];
force[1] = force[0];
return filter[0];
}
(Formula here makes no sense) But now system is working (...Ok , with a formula that makes no sense but it works). If I press button I see the pulse in the PLC that is read back from the PLC itself within the form and so I see it reflected in force[0]. This is what I need to do but with the second code sample formula.
So it seems to me there is someting related with the float management. I cannot use the double type because both SyncRead and SyncWrite return an error.
With reference to my first code sample
public static void Write_synchr(RSIOPC r)
{
try
{
DataToSend.SetValue(r.array_to_send, 1);
r.RSLinxOPCgroup_w.SyncWrite(1, ref r.SyncServerHandles_w, ref DataToSend, out SyncErrors2);
}
catch (Exception e)
{
MessageBox.Show(e.ToString(), "Error: ",
MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
In the loop I set the value of r.array_to_send[0] with the value of filter[0] and the value of r.array_to_send[1] with the value of the pulse generated with the button in the form.
I like to remember that with the following formula I have no problem at all
r.array_to_send[0] = (float)(2 * Math.Cos((2 * (1.0 / Time_period[0]) * Math.PI) * t));
I tried with other formulas and this is the result
filter[0] = (float) (force[0] + 0.0 + filter[2]); NOT WORKING
filter[0] = (float) (force[0] + 0.000001 + filter[2]); NOT WORKING
filter[0] = (float) (force[0] + 0.0001 + filter[2]); WORKING
|
|
|
|
|
You are possibly mixing float s and double s in there: we can't see the definition of the force or filter arrays, but the casting kinda implies the type.
So if force is an array of float values, then when you do this:
filter[0] = (float) (force[0] + 0.0 + filter[2]); The system is obliged to implicitly cast the force elements to double in order to do the addition, and that may be what is causing imprecision, and thus an error (we can't tell what you should have or what you get, so "NOT WORKING" isn't particularly helpful!)
You could try keeping it all in float values and see if that helps:
filter[0] = (float) (force[0] + 0.0F + filter[2]);
If not, then you need to use the debugger to find out what values exist in the force array, and what values you actually get / expect as a result.
"I have no idea what I did, but I'm taking full credit for it." - ThisOldTony
"Common sense is so rare these days, it should be classified as a super power" - Random T-shirt
AntiTwitter: @DalekDave is now a follower!
|
|
|
|
|
Ok
What looks so strange to me is anyhow why when I use 0.0001 instead of 0.0 I do not have the problem , (I tried also with other numbers and some give the problem, others do not).
Again, why the formula of the sine wave runs apparently correctly.
OK when I say working I mean apparently working without defects behaving like it is expected to.
Ex. I press the button, I read the pulse value back in the form after that SyncWrite transmitted to PLC , PLC trasferred to another tag, and form read back the new tag with the correct value
When I say not working I mean that strange behaviour that while pressing value is not transferred at all to the PLC (or at least it seems) or in other cases sometimes it is transferred and sometimes not .
This also followed by occasionally popup error windows telling about access violation when executing the SyncWrite.
Both Force and Filter arrays are declared float so in my opinion (just an opinion) the "true" filter algorithm should be ok, unless anytime I multiply or divide a mix of double and float is generated.
Debugging I look inside the value of the arrays and I can only see decimal numbers with comma so I cannot distinguish if they are float or double. Is there a way for this?
Thanks very much
|
|
|
|
|
When you mix float and double in the same expression, they have to "equalized" so you are working with the same type of values - much like when you multiply an integer by floating point value, you need to return a float in order to have any accuracy: 13 * 0.6 = 7.8 if you convert the integer to a float, but 13 * 0.6 = 0 if you convert the float to an int!
And a "normal" floating point constant is always a double unless you add the 'F' suffix to make it a float
And the implicit casting that the system does is always "upwards": byte to int, int to float or double, float to double, never the other way around.
So the float values in your array are converted to double values, multiplied by a double constant, and the result is cast - by you - back to a float .
And the problem is that numbers aren't stored in decimal: they are stored in binary (technically in IEEE-754 floating-point standard) and some values just don't "store well": What Every Computer Scientist Should Know About Floating-Point Arithmetic[^]
When you start converting from one floating point size to another, these problems can become exacerbated - which is why the decimal type exists to "reduce the precision" and make things more accurate as a result!
"I have no idea what I did, but I'm taking full credit for it." - ThisOldTony
"Common sense is so rare these days, it should be classified as a super power" - Random T-shirt
AntiTwitter: @DalekDave is now a follower!
|
|
|
|
|
So you think that a solution is to use decimal type? Or even this could have the same problem? At the end I will have to solve this, so if the only way is example to use integers (fixed comma) I can do that.
What is your suggestion?
Just for curiosity, this type of problem is relevant only to float type or also to double?
Thanks
Regards
|
|
|
|
|
Doubles and floats have the same problem: for example 0.1 and 0.2 can't be stored in a floating point format because they are a recurring number in binary, so 0.1 + 0.2 != 0.3 :
float fp1 = 0.1F;
float fp2 = 0.2F;
string result = (fp1 + fp2) == 0.3F ? "Yes" : "No";
Debug.WriteLine($"{fp1} + {fp2} = 0.3? {result}");
double dp1 = 0.1;
double dp2 = 0.2;
result = (dp1 + dp2) == 0.3 ? "Yes" : "No";
Debug.WriteLine($"{dp1} + {dp2} = 0.3? {result}");
Will give you:
0.1 + 0.2 = 0.3? No
0.1 + 0.2 = 0.3? No
I suspect that decimal may help, but to be honest I have no idea what you are trying to achieve, or what values you are actually looking at and expecting, do I can't recommend them as a "fix".
"I have no idea what I did, but I'm taking full credit for it." - ThisOldTony
"Common sense is so rare these days, it should be classified as a super power" - Random T-shirt
AntiTwitter: @DalekDave is now a follower!
|
|
|
|
|
My goal is only to pass to a RsiOpc.dll (from Rockwell) routine SyncWrite a number (or an array of them) that have only to be transferred to a PLC.
When I used integers i never had a problem. Now I would like to use decimal (I simply mean numbers with comma).
Then as I said I used also (what follows I took from the code directly, the samples I posted before are translated from italian where array_to_send is array_da_inviare)
r.array_da_inviare_D[0] = (float)(2 * Math.Cos((2 * (1.0 / periodo_sinusoide[0]) * Math.PI) * sec_tot));
Why this doesn't generate the problem? There are decimal,integers mixed and the result is a double as you say and in fact I converted everything to float to pass the value to array_da_inviare[0]
What I need to do is, instead of a sine wave, send just a value (at any cycle) that is the result of a second order filter
The filter formula is coming from its Laplace representation in S then passes into the discrete transformation Z and at the end becomes a quite easy formula being an algebric sum of some variables multiplied by some factors and divided by other factors. The result is simply another number that must transitate to a PLC. The real formula is exactly that of the second sample code. Just nothing more than this.
Meanwhile I convered filter and force array from float to decimal. So now code is:
decimal filter_result;
filter_result = filter();
r.array_da_inviare_D[0] = (float) (filter_result);
but also this way I have the problem
modified 19-Feb-21 8:36am.
|
|
|
|
|
Ok
I tested a bit different version where when I press the button which generates the pulse, this pulse doesn't go only to the PLC and is read back with the SyncRead but first of all goes directly to force[0]
then it is also copied to array_to_send[1] in order to be trended by the plc and as ever it is read back in the form. But main point here is that force[0] is fed directly with the pulse.
This way seems to be working using the correct formula for the second order filter unless some error messages coming sometimes with no evident frequency, not very often. Message, as I said in the previous posts, tells about access violation executing the SyncWrite.
This is interesting in my opinion since can be a sign of something going wrong in the very first moment of the filtering function when probably values inside the two arrays force and filter lead tio some mathematical error not well managed in the treatment of the float type if the force[0] is fed with the SyncWrite /SyncRead. While when it is fed directly probably numbers in the two arrays assess in a way that doesn't cause problems.
Could it be?
While
|
|
|
|
|
Even if the numbers of this elaboration are quite small (inthe sense that the force that I apply is in the unit order like 1, 2, 3 ,4 .... and the parameters of the filters lead to other small numbers and so the data to exchange with the SyncWrite are small (example < 10) the only way I found is to divide this number by 1 million within the c# code and then on the PLC side multiply by 1 million. (1 million is the best solution I found. I tried also 10'000 or 100'000 but with them sometimes an access violation is generated. Probably, using factor greater than 1 million can even better the situation, I do not know)
|
|
|
|
|