ok so basically i translated this xor converter from javascript so i can xor strings faster by c+p my c++ code and it just replaces all the strings with xor'd ones for me, but this xors all strings with the first xor it created for the first string any help with this would be greatly appreciated. i tried creating a loop but i just failed and gave up. that is probably what i need to do i just need someone to show me how i should set it up.
string Dec2Hex(int test)
{
string hex = test.ToString("X");
return hex;
}
string symbols = " !\"#$%&'()*+,-./0123456789:;<=>?#";
int toAscii(string xx)
{
var loAZ = "abcdefghijklmnopqrstuvwxyz";
symbols += loAZ.ToUpper();
symbols += "[\\]^_`";
symbols += loAZ;
symbols += "{|}~";
int loc;
loc = symbols.IndexOf(xx);
if (loc > -1)
{
//Ascii_Decimal = 32 + loc;
return (32 + loc);
}
return (0); // If not in range 32-126 return ZERO
}
byte[] randByte()
{
Byte[] RandByte = new Byte[5];
new Random().NextBytes(RandByte);
return RandByte;
}
public void RunEncrypter()
{
string test = textBox1.Text;
System.Text.RegularExpressions.Regex x = new System.Text.RegularExpressions.Regex("\"(.*?)\"", System.Text.RegularExpressions.RegexOptions.Singleline);
var matches = x.Matches(textBox1.Text);
string s1 = "";
if (matches.Count <= 0)
return;
s1 = matches[0].Groups[1].Value;
byte[] randombyte = randByte();
double xvaluestart = randombyte[0];
string xrefkill = "0x" + Dec2Hex(randombyte[1]) + Dec2Hex(randombyte[2]) + Dec2Hex(randombyte[3]) + Dec2Hex(randombyte[4]);
int finallen = s1.Length + 1;
string hexsequence = "\"";
double xvalue = xvaluestart;
for (int i = 0; i < s1.Length; i++)
{
string ch = s1.Substring(i, 1);
int chval;
chval = toAscii(ch);
if (chval == 0) { s1 = "invalid character: " + ch; return; }
chval ^= (int)xvalue;
xvalue += 1;
xvalue %= 256;
hexsequence += "\\x" + Dec2Hex(chval);
}
hexsequence += '"';
string s2 = "/*" + s1 + "*/XorStr<0x" + Dec2Hex((int)xvaluestart) + "," + finallen + "," + xrefkill + ">(";
s2 += hexsequence + "+" + xrefkill + ").s";
textBox1.Text = x.Replace(textBox1.Text, s2);
}
private void button1_Click(object sender, EventArgs e)
{
RunEncrypter();
}
I do not fully understand what you are trying but a simple XOR cipher can be implemented in C# as simple as that:
static string Xor(string text, int key)
{
string result = "";
for (int i = 0; i < text.Length; i++)
{
int charValue = Convert.ToInt32(text[i]); //get the ASCII value of the character
charValue ^= key; //xor the value
result += char.ConvertFromUtf32(charValue); //convert back to string
}
return result;
}
This algorithm goes through each character in the string, convert it to its integer ASCII value, xor the value with the key, and convert the new value back into a string.
Related
I have a problem with string in C#. I get this string from database, and it contains quote signs ("), so my program doesn't read it correctly.
string attributes = databaseFunctions.GetVariationAttributes(produc_id);
My string in the database is
a:3:{s:9:"variation";a:6:{s:4:"name";s:9:"Variation";s:5:"value";s:24:"type a | type b | type c";s:8:"position";s:1:"0";s:10:"is_visible";s:1:"1";s:12:"is_variation";s:1:"1";s:11:"is_taxonomy";s:1:"0";}s:5:"color";a:6:{s:4:"name";s:5:"Color";s:5:"value";s:27:"RED | BLUE | WHITE | ORANGE";s:8:"position";s:1:"1";s:10:"is_visible";s:1:"1";s:12:"is_variation";s:1:"1";s:11:"is_taxonomy";s:1:"0";}s:4:"test";a:6:{s:4:"name";s:4:"TEST";s:5:"value";s:15:"120 | 140 | 160";s:8:"position";s:1:"2";s:10:"is_visible";s:1:"1";s:12:"is_variation";s:1:"0";s:11:"is_taxonomy";s:1:"0";}}
This is actually the Woocommerce product variation attributes. I need to get each attribute, check if it is used for variations, and if yes, get its name and possible values.
Maybe you have any idea how to do it? I'm trying to use substrings and IndexOf functions (Get index of the first and second colon, then get value from between them and use it in a loop)
I will appreciate any of your advice
[EDIT]
Ok, I did it. It's not the prettiest solution, but it works. I post it here, so others may use it in a similar situation
if(databaseFunctions.CheckVariations(variations))
{
string attributes = databaseFunctions.GetVariationAttributes(produc_id);
List<List<string>> parameters = new List<List<string>>();
List<List<string>> values = new List<List<string>>();
int i_1 = 0;
int i_2 = 0;
//First ':'
int c_1 = attributes.IndexOf(':');
//Second ':'
int c_2 = attributes.IndexOf(':', c_1 + 1);
//First 'a' - number of attributes
int a_1 = Convert.ToInt32(attributes.Substring(c_1 + 1, c_2-c_1 -1));
//For each attribute
for (int i = 0; i < a_1; i++)
{
List<string> parameters_of_attribute = new List<string>();
List<string> values_of_attribute = new List<string>();
//First ':'
int ac_1 = attributes.IndexOf(':', c_2 + 1 + i_1);
//Second ':'
int ac_2 = attributes.IndexOf(':', ac_1 + 1);
//First ':' of a
int kc_1 = attributes.IndexOf(':', ac_2 + 1);
//Second ':' of a
int kc_2 = attributes.IndexOf(':', kc_1 + 1);
//Number of parameter-value pairs
int p_v = Convert.ToInt32(attributes.Substring(kc_1 + 1, kc_2 - kc_1 - 1));
//For each parameter-value pair
for (int j = 0; j < p_v; j++)
{
//First '"' of parameter
int pq_1 = attributes.IndexOf('"', kc_2 + 1 + i_2);
//Second '"' of parameter
int pq_2 = attributes.IndexOf('"', pq_1 + 1);
//Name of parameter
string par = attributes.Substring(pq_1 + 1, pq_2 - pq_1 - 1);
//First '"' of value
int vq_1 = attributes.IndexOf('"', pq_2 + 1);
//Second '"' of value
int vq_2 = attributes.IndexOf('"', vq_1 + 1);
//Value of parameter
string val = attributes.Substring(vq_1 + 1, vq_2 - vq_1 - 1);
parameters_of_attribute.Add(par);
values_of_attribute.Add(val);
i_2 = vq_2 - kc_2;
}
parameters.Add(parameters_of_attribute);
values.Add(values_of_attribute);
i_1 = i_2 + kc_2 - c_2;
i_2 = 0;
}
}
Gordon Breuer published code to read PHP's serialized data format using C# at https://gordon-breuer.de/unknown/2011/05/04/php-un-serialize-with-c.html - unfortunately this is not available as a NuGet package (yet!) - it's based off dinosaur code written for .NET Framework 1.0 back in 2001.
I'm repeating the code below for preservation's sake with extra copyright/origin info (Blogs aren't around forever). According to the original SourceForge project's page the code is licensed under the OSI-approved IBM CPL.
/*
* Serializer.cs
* This is the Serializer class for the PHPSerializationLibrary
*
* https://sourceforge.net/projects/csphpserial/
*
* Copyright 2004 Conversive, Inc. Licensed under Common Public License 1.0
*
* Modified for WP7-Silverlight by Gordon Breuer
* https://gordon-breuer.de/unknown/2011/05/04/php-un-serialize-with-c.html
*
* Updated to be thread-safe and correctly reentrant and with C# 7.0 features added for https://stackoverflow.com/questions/58384540/c-sharp-string-with-from-database-cannot-do-interpolation/
*
*/
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Text;
namespace Conversive.PHPSerializationLibrary {
public class PhpSerializer
{
//types:
// N = null
// s = string
// i = int
// d = double
// a = array (hashtable)
private static readonly NumberFormatInfo _nfi = new NumberFormatInfo { NumberGroupSeparator = "", NumberDecimalSeparator = "." };
public Encoding StringEncoding { get; }
/// <summary>Whether or not to strip carriage returns from strings when serializing and adding them back in when deserializing</summary>
public Boolean XmlSafe { get; }
public PhpSerializer()
: this( encoding: new UTF8Encoding(), xmlSafe: true )
{
}
public PhpSerializer( Encoding encoding, Boolean xmlSafe )
{
this.StringEncoding = encoding ?? throw new ArgumentNullException(nameof(encoding));
this.XmlSafe = xmlSafe;
}
private class SerializeState
{
public readonly StringBuilder sb = new StringBuilder();
// These collections used for cycle-detection.
public readonly HashSet<Object> seenCollections = new HashSet<Object>();
}
public String Serialize(object obj)
{
SerializeState state = new SerializeState();
this.Serialize(obj, state );
return state.sb.ToString();
}
//Serialize(object obj)
private void Serialize( Object obj, SerializeState state )
{
StringBuilder sb = state.sb;
if (obj == null)
{
sb.Append("N;");
}
else if (obj is string str)
{
if (XmlSafe)
{
str = str.Replace("rn", "n"); //replace rn with n
str = str.Replace("r", "n"); //replace r not followed by n with a single n Should we do this?
}
sb.Append("s:" + StringEncoding.GetByteCount(str) + ":" + str + ";");
}
else if (obj is bool b)
{
sb.Append("b:" + ( b ? "1" : "0") + ";");
}
else if (obj is int objInt)
{
sb.Append("i:" + objInt.ToString(_nfi) + ";");
}
else if (obj is double objDbl)
{
sb.Append("d:" + objDbl.ToString(_nfi) + ";");
}
else if ( (obj is IReadOnlyDictionary<object, object> ) || ( obj is IDictionary<object, object> ) )
{
if (state.seenCollections.Contains(obj))
{
sb.Append("N;");
}
else
{
state.seenCollections.Add(obj);
IEnumerable<KeyValuePair<Object,Object>> asDictEnum = (IEnumerable<KeyValuePair<Object,Object>>)obj;
sb.Append("a:" + asDictEnum.Count() + ":{");
foreach (var entry in asDictEnum)
{
this.Serialize(entry.Key, state);
this.Serialize(entry.Value, state);
}
sb.Append("}");
}
}
else if (obj is IEnumerable<object> enumerable)
{
if (state.seenCollections.Contains( enumerable ) )
{
sb.Append("N;");
}
else
{
state.seenCollections.Add(enumerable);
IReadOnlyList<Object> asList = enumerable as IReadOnlyList<Object>; // T[] / Array<T> implements IReadOnlyList<T> already.
if( asList == null ) asList = enumerable.ToList();
sb.Append("a:" + asList.Count + ":{");
Int32 i = 0;
foreach( Object item in asList )
{
this.Serialize(i, state);
this.Serialize( item, state);
i++;
}
sb.Append("}");
}
}
else
{
throw new SerializationException( "Value could not be serialized." );
}
}
public Object Deserialize(String str)
{
Int32 pos = 0;
return this.Deserialize(str, ref pos );
}
private Object Deserialize( String str, ref Int32 pos )
{
if( String.IsNullOrWhiteSpace( str ) )
return new Object();
int start, end, length;
string stLen;
switch( str[pos] )
{
case 'N':
pos += 2;
return null;
case 'b':
char chBool = str[pos + 2];
pos += 4;
return chBool == '1';
case 'i':
start = str.IndexOf(":", pos) + 1;
end = str.IndexOf(";", start);
var stInt = str.Substring(start, end - start);
pos += 3 + stInt.Length;
return Int32.Parse(stInt, _nfi);
case 'd':
start = str.IndexOf(":", pos) + 1;
end = str.IndexOf(";", start);
var stDouble = str.Substring(start, end - start);
pos += 3 + stDouble.Length;
return Double.Parse(stDouble, _nfi);
case 's':
start = str.IndexOf(":", pos) + 1;
end = str.IndexOf(":", start);
stLen = str.Substring(start, end - start);
var bytelen = Int32.Parse(stLen);
length = bytelen;
if ((end + 2 + length) >= str.Length) length = str.Length - 2 - end;
var stRet = str.Substring(end + 2, length);
while (StringEncoding.GetByteCount(stRet) > bytelen)
{
length--;
stRet = str.Substring(end + 2, length);
}
pos += 6 + stLen.Length + length;
if (XmlSafe) stRet = stRet.Replace("n", "rn");
return stRet;
case 'a':
start = str.IndexOf(":", pos) + 1;
end = str.IndexOf(":", start);
stLen = str.Substring(start, end - start);
length = Int32.Parse(stLen);
var htRet = new Dictionary<object, object>(length);
var alRet = new List<object>(length);
pos += 4 + stLen.Length; //a:Len:{
for (int i = 0; i < length; i++)
{
var key = this.Deserialize(str, ref pos);
var val = this.Deserialize(str, ref pos);
if (alRet != null)
{
if (key is int && (int)key == alRet.Count)
alRet.Add(val);
else
alRet = null;
}
htRet[key] = val;
}
pos++;
if( pos < str.Length && str[pos] == ';')
{
pos++;
}
return alRet != null ? (object)alRet : htRet;
default:
return "";
}
}
}
}
When I run this in Linqpad with your input I get this result output:
void Main()
{
const String attribs = #"a:3:{s:9:""variation"";a:6:{s:4:""name"";s:9:""Variation"";s:5:""value"";s:24:""type a | type b | type c"";s:8:""position"";s:1:""0"";s:10:""is_visible"";s:1:""1"";s:12:""is_variation"";s:1:""1"";s:11:""is_taxonomy"";s:1:""0"";}s:5:""color"";a:6:{s:4:""name"";s:5:""Color"";s:5:""value"";s:27:""RED | BLUE | WHITE | ORANGE"";s:8:""position"";s:1:""1"";s:10:""is_visible"";s:1:""1"";s:12:""is_variation"";s:1:""1"";s:11:""is_taxonomy"";s:1:""0"";}s:4:""test"";a:6:{s:4:""name"";s:4:""TEST"";s:5:""value"";s:15:""120 | 140 | 160"";s:8:""position"";s:1:""2"";s:10:""is_visible"";s:1:""1"";s:12:""is_variation"";s:1:""0"";s:11:""is_taxonomy"";s:1:""0"";}}";
PhpSerializer s = new PhpSerializer();
Object result = s.Deserialize( attribs );
result.Dump();
}
Visualized output:
i want to get the char of an ascii give by a certain position of a string on c# but i can't reach te correct way.
Code:
string Str;
string StrEnd;
int Clave = 0;
Str = txtStr.Text;
Clave = Convert.ToInt32(txtCv.Text);
for (int i = 0; i == Str.Length - 1; i++)
{
StrEnd = (char)Encoding.ASCII.GetBytes(Str[index: i]) + Clave;
}
For EG.
Str = "ABC" , and var Clave = 1 then string StrEnd would look like this "BCD".
other example would be...
Str = "Hola", Clave = 2 then StrEnd = "Jqnc"
if still not clear, please tell me.
Thanks in advance.
Another approach is as below,
string Str = txtStr.Text;
string StrEnd = string.Empty;
int clave = Convert.ToInt32(txtCv.Text);
foreach(char c in Str)
{
StrEnd += (char)(c + clave);
}
It's missing a Linq solution:
(If the C# version in use doesn't allow an auto [out] parameter, add int key = 0;).
string Str = "Hola";
if (int.TryParse(txtCv.Text, NumberStyles.Integer, CultureInfo.CurrentCulture, out int key))
{
string StrEnd = string.Join("", Str.Select(c => (char)(c + key)));
}
With key == 2: StrEnd = "Jqnc"
Here is a working solution :
string StrEnd="";
string Str = txtStr.Text;
int Clave = Convert.ToInt32(txtCv.Text);
for (int i = 0; i < Str.Length; i++)
{
StrEnd += (char)(Str[i] + Clave);
}
I tested code on Console Application. Please change it to your needed application. But the logic works as you asked.
static void Main(string[] args)
{
string Str;
string StrEnd = string.Empty;
int Clave = 1;
Str = "ABC";
foreach (char c in Str)
{
byte[] asciiBytes = Encoding.ASCII.GetBytes(new char[] { c });
asciiBytes[0] = (byte) (asciiBytes[0] + Clave);
StrEnd += Encoding.UTF8.GetString(asciiBytes);
}
Console.WriteLine(StrEnd);
Console.ReadLine();
}
Summary of this code
Str = "ABC"; Clave = 1; StrEnd="BCD";
I have tried writing the logic for reversing each word in a string with single loop but I didn't get it to work. Can you please provide the logic to reverse every word in a string using single loop and without using reverse function.
Input:
Welcome to the world
Output:
emocleW ot eht dlrow
My Logic with two loops:
class Program
{
static void Main(string[] args)
{
string input = string.Empty;
input = Console.ReadLine();
string[] strarr=input.Split(' ');
StringBuilder sb = new StringBuilder();
foreach (string str in strarr)
{
sb.Append(fnReverse(str));
sb.Append(' ');
}
Console.WriteLine(sb);
Console.Read();
}
public static string fnReverse(string str)
{
string result = string.Empty;
for (int i = str.Length-1; i >= 0; i--)
result += str[i];
return result;
}
}
string strIn = "Welcome to the world";
string strTmp = "";
string strOut = "";
for (int i=strIn.Length-1; i>-1; i--)
{
if (strIn[i] == ' ')
{
strOut = strTmp + " " + strOut;
strTmp = "";
}
else
{
strTmp += strIn[i];
}
}
strOut = strTmp + " " + strOut;
Gives the result "emocleW ot eht dlrow"
string input = Console.ReadLine();
string result = "";
string tmp = "";
for (int i = input.Length - 1; i >= 0; i--)
{
if (input[i] == ' ')
{
result = tmp + " " + result;
tmp = "";
}
else
tmp += input[i];
}
result = tmp + " " + result;
Console.WriteLine(result);
Here is the DEMO
I have this function to decrypt connection strings in VB .NET, and I try to bring it to C#:
Function DecryptText(strText As String, ByVal strPwd As String)
Dim i As Integer, c As Integer
Dim strBuff As String
#If Not CASE_SENSITIVE_PASSWORD Then
'Convert password to upper case
'if not case-sensitive
strPwd = UCase$(strPwd)
#End If
'Decrypt string
If Len(strPwd) Then
For i = 1 To Len(strText)
c = Asc(Mid$(strText, i, 1))
c = c - Asc(Mid$(strPwd, (i Mod Len(strPwd)) + 1, 1))
strBuff = strBuff & Chr$(c & &HFF)
Next i
Else
strBuff = strText
End If
DecryptText = strBuff
End Function
I tried with these two ways:
public static string DesencriptarCadena(this string cadena, string llave = "asdf")
{
try
{
cadena = cadena.Replace("\r", "").Replace("\n", "");
byte b = 0;
string strBuff = "";
System.Text.Encoding encoding = System.Text.Encoding.Default;
for (int i = 0; i < cadena.Length; i++)
{
b = encoding.GetBytes(cadena.ToCharArray(), i, 1)[0];
int ind = i % llave.Length;
b -= encoding.GetBytes(llave.ToCharArray(), ind, 1)[0];
strBuff += encoding.GetChars(new byte[] { Convert.ToByte((int)b & +0xff) })[0];
}
return strBuff;
}
catch (Exception ex)
{
return cadena;
}
}
or this other way:
public static string DesencriptarCadena(this string cadena, string llave = "asdf")
{
try
{
cadena = cadena.Replace("\r", "").Replace("\n", "");
int c;
string strBuff = "";
System.Text.Encoding encoding = System.Text.Encoding.Default;
for (int i = 0; i < cadena.Length; i++)
{
int ind = i % llave.Length;
c = cadena[i];
c -= llave[ind];
strBuff += Convert.ToChar(c & +0xff);
}
return strBuff;
}
catch (Exception ex)
{
return cadena;
}
}
But, it doesn't work. Can someone explain to me what I should do?
In the first way return:
ÞÓÚÏË×ÞÓÚÏË×ÞÓÚÏ ÞÓÚÏË×ÞÓÚÏú×ÞÓÚÏË×ÞÓÚÏË×ÞÓÚÏË×ÞÚÏË×ÞÓÚÏË×Þ
In the second: NúÎCÄÁÎî
It is not returning the decrypted connection string.
http://converter.telerik.com has always done great by me for these types of conversions. Let me know how this works.
public object DecryptText(string strText, string strPwd)
{
int i = 0;
int c = 0;
string strBuff = null;
#if Not CASE_SENSITIVE_PASSWORD
//Convert password to upper case
//if not case-sensitive
strPwd = Strings.UCase(strPwd);
#endif
//Decrypt string
if (Strings.Len(strPwd)) {
for (i = 1; i <= Strings.Len(strText); i++) {
c = Strings.Asc(Strings.Mid(strText, i, 1));
c = c - Strings.Asc(Strings.Mid(strPwd, (i % Strings.Len(strPwd)) + 1, 1));
strBuff = strBuff + Strings.Chr(c + 0xff);
}
} else {
strBuff = strText;
}
return strBuff;
}
After including the Microsoft.VisualBasic assembly, I added two using statements:
using Microsoft.VisualBasic;
using Microsoft.VisualBasic.CompilerServices;
I compiled it and decompiled it with dotPeek. It resulted in this:
public static object DecryptText(string strText, string strPwd)
{
string str = string.Empty;
strPwd = Strings.UCase(strPwd);
if ((uint)Strings.Len(strPwd) > 0U)
{
int num1 = 1;
int num2 = Strings.Len(strText);
int Start = num1;
while (Start <= num2)
{
int num3 = checked(Strings.Asc(Strings.Mid(strText, Start, 1)) - Strings.Asc(Strings.Mid(strPwd, unchecked(Start % Strings.Len(strPwd)) + 1, 1)));
str = str + Conversions.ToString(Convert.ToChar(Conversions.ToString(num3) + Conversions.ToString((int)byte.MaxValue)));
checked { ++Start; }
}
}
else
str = strText;
return (object)str;
}
I have a string value that its length is 5000 + characters long , i want to split this into 76 characters long with a new line at the end of each 76 characters. how woudld i do this in c#?
If you're writing Base64 data, try writing
Convert.ToBase64String(bytes, Base64FormattingOptions.InsertLineBreaks);
This will insert a newline every 76 characters
A side on this, if you want StringBuilder versus string performance the best article is the codeproject one found here.
(This doesn't show string size however)
In a nutshell, StringBuilder isn't faster until a threshold is met with the string length (or repeated contactenation), which you're well under, so stick the regular string concatenation and String methods.
Try this:
s = Regex.Replace(s, #"(?<=\G.{76})", "\r\n");
EDIT: Apparently, this is the slowest method of all those posted so far. I wonder how it does if you pre-compile the regex:
Regex rx0 = new Regex(#"(?<=\G.{76})");
s = rx0.Replace(s, "\r\n"); // only time this portion
Also, how does it compare to a straight matching approach?
Regex rx1 = new Regex(".{76}");
s = rx1.Replace(s, "$0\r\n"); // only time this portion
I've always wondered how expensive those unbounded lookbehinds are.
A little uglier ... but much faster ;) (this version took 161 ticks... Aric's took 413)
I posted my test code on my blog. http://hackersbasement.com/?p=134
(I also found StringBuilder to be much slower than string.Join)
http://hackersbasement.com/?p=139 <= updated results
string chopMe = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
Stopwatch sw = new Stopwatch();
sw.Start();
char[] chopMeArray = chopMe.ToCharArray();
int totalLength = chopMe.Length;
int partLength = 12;
int partCount = (totalLength / partLength) + ((totalLength % partLength == 0) ? 0 : 1);
int posIndex = 0;
char[] part = new char[partLength];
string[] parts = new string[partCount];
int get = partLength;
for (int i = 0; i < partCount; i++)
{
get = Math.Min(partLength, totalLength - posIndex);
Array.Copy(chopMeArray, posIndex, part, 0, get);
parts[i] = new string(part, 0, get);
posIndex += partLength;
}
var output = string.Join("\r\n", parts) + "\r\n";
sw.Stop();
Console.WriteLine(sw.ElapsedTicks);
public static string InsertNewLine(string s, int len)
{
StringBuilder sb = new StringBuilder(s.Length + (int)(s.Length/len) + 1);
int start = 0;
for (start=0; start<s.Length-len; start+=len)
{
sb.Append(s.Substring(start, len));
sb.Append(Environment.NewLine);
}
sb.Append(s.Substring(start));
return sb.ToString();
}
where s would be your input string and len the desired line length (76).
string[] FixedSplit(string s, int len)
{
List<string> output;
while (s.Length > len)
{
output.Add(s.Substring(0, len) + "\n");
s.Remove(0, len);
}
output.Add(s + "\n");
return output.ToArray();
}
public static IEnumerable<string> SplitString(string s, int length)
{
var buf = new char[length];
using (var rdr = new StringReader(s))
{
int l;
l = rdr.ReadBlock(buf, 0, length);
while (l > 0)
{
yield return (new string(buf, 0, l)) + Environment.NewLine;
l = rdr.ReadBlock(buf, 0, length);
}
}
}
Then to put them back together:
string theString = GetLongString();
StringBuilder buf = new StringBuilder(theString.Length + theString.Length/76);
foreach (string s in SplitString(theString, 76) { buf.Append(s); }
string result = buf.ToString();
Or you could do this:
string InsertNewLines(string s, int interval)
{
char[] buf = new char[s.Length + (int)Math.Ceiling(s.Length / (double)interval)];
using (var rdr = new StringReader(s))
{
for (int i=0; i<buf.Length-interval; i++)
{
rdr.ReadBlock(buf, i, interval);
i+=interval;
buf[i] = '\n';
}
if (i < s.Length)
{
rdr.ReadBlock(buf, i, s.Length - i);
buf[buf.Length - 1] = '\n';
}
}
return new string(buf);
}
One more.... (first time through slowish, subsequent runs, similar to the faster times posted above)
private void button1_Click(object sender, EventArgs e)
{
string chopMe = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
Stopwatch sw = new Stopwatch();
sw.Start();
string result = string.Join("\r\n", ChopString(chopMe).ToArray());
sw.Stop();
MessageBox.Show(result + " " + sw.ToString());
}
public IEnumerable<string> ChopString(string s)
{
int i = 0;
while (i < s.Length)
{
yield return i + PARTLENGTH <= s.Length ? s.Substring(i,PARTLENGTH) :s.Substring(i) ;
i += PARTLENGTH;
}
}
Edit: I was curious to see how fast substring was...
The string is 5000 characters... I don't think speed is really of the essence unless you're doing this thousands or maybe even millions of times, especially when the OP didn't even mention speed being important. Premature optimization?
I would probably use recursion as it will, in my opinion, lead to the simplest code.
This may not be syntatically correct, as I know .NET but not C#.
String ChunkString(String s, Integer chunkLength) {
if (s.Length <= chunkLength) return s;
return String.Concat(s.Substring(0, chunkLength),
ChunkString(s.Substring(chunkLength)));
}
mostly for the fun of it, here's a different solution implemented as extension method to string:
(\r\n used explicitly so will only support that format for newline);
public static string Split(this string str, int len)
{
char org = str.ToCharArray();
int parts = str.Length / len + (str.Length % len == 0 ? 0 : 1);
int stepSize = len + newline.Length;
char[] result = new char[parts * stepSize];
int resLen = result.Length;
for (int i =0;i<resLen ;i+stepSize)
{
Array.Copy(org,i*len,result,i*stepSize);
resLen[i++] = '\r';
resLen[i++] = '\n';
}
return new string(result);
}
In the end, this would be what I would use, I think
static string fredou()
{
string s = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
int partLength = 12;
int stringLength = s.Length;
StringBuilder n = new StringBuilder(stringLength + (int)(stringLength / partLength) + 1);
int chopSize = 0;
int pos = 0;
while (pos < stringLength)
{
chopSize = (pos + partLength) < stringLength ? partLength : stringLength - pos;
n.Append(s , pos, chopSize);
n.Append("\r\n");
pos += chopSize;
}
return n.ToString();
}
by looking at AppendLine under reflector:
<ComVisible(False)> _
Public Function AppendLine(ByVal value As String) As StringBuilder
Me.Append(value)
Return Me.Append(Environment.NewLine)
End Function
Public Shared ReadOnly Property NewLine As String
Get
Return ChrW(13) & ChrW(10)
End Get
End Property
For me, speed wise, doing it manually > AppendLine
I'm spliting the string by 35
var tempstore ="12345678901234567890123456789012345";
for (int k = 0; k < tempstore.Length; k += 35)
{
PMSIMTRequest.Append(tempstore.Substring(k, tempstore.Length - k > 35 ? 35 : tempstore.Length - k));
PMSIMTRequest.Append(System.Environment.NewLine);
}
messagebox.Show(PMSIMTRequest.tostring());
#M4N's answer is very good , but I think while statement is easier to understand than for statement.
public static string InsertNewLine(string source, int len = 76)
{
var sb = new StringBuilder(source.Length + (int)(source.Length / len) + 1);
var start = 0;
while ((start + len) < source.Length)
{
sb.Append(source.Substring(start, len));
sb.Append(Environment.NewLine);
start += len;
}
sb.Append(source.Substring(start));
return sb.ToString();
}