Skip to content

Instantly share code, notes, and snippets.

@waynebaby
Created November 5, 2012 09:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save waynebaby/4016356 to your computer and use it in GitHub Desktop.
Save waynebaby/4016356 to your computer and use it in GitHub Desktop.
----------------------------------Unsafe Code---------------------
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
namespace WordsRandom
{
class Program
{
static void Main(string[] args)
{
do
{
var str = Console.ReadLine();
RandomWords(str);
Console.WriteLine(str);
} while (true);
}
public struct Pair<TX, TY>
{
public TX X;
public TY Y;
}
public struct Pair
{
public static Pair<TX, TY> Create<TX, TY>(TX x, TY y)
{
return new Pair<TX, TY> { X = x, Y = y };
}
}
static Random _rnd = new Random();
static HashSet<char> _splitChars = new HashSet<char> { '\'', '.', ' ', '\r', '\t', '\n' };
static unsafe void RandomWords(string content)
{
var spaceMarks = System.Linq.Enumerable.Concat(" ", content).Concat(" ")
.Select((c, i) => Pair.Create(c, i-1))
.Where(p => _splitChars.Contains(p.X))
.Select(p => p.Y);
var segs = spaceMarks
.Zip(spaceMarks.Skip(1), (x, y) => Pair.Create(x+ 2, y-x-3)) //对空格进行两两配对计算混淆的起止坐标
.Where(p => p.Y > 1); //没有内容可混淆的过滤掉
fixed (char* ptr = content)
{
foreach (var seg in segs)
{
RandomArea(seg, ptr);
}
}
}
static unsafe public void RandomArea(Pair<int, int> marks, char* array)
{
// var chars = new char[segment.Count];
int Offset = marks.X;
int Count = marks.Y;
for (int i = 0; i < Count; i++)
{
char tempChar;
var remains = Count - i;//随着循环进行,可以取出的范围减少
var last = remains + Offset - 1;
//随机取出一个 和剩余没有抽取的最后元素交换。最后的元素们就是结果
var chosen = _rnd.Next(0, remains) + Offset;
tempChar = array[chosen];
array[chosen] = array[last];
array[last] = tempChar;
}
}
}
}
-----------------------------------Safe Managed code------------------------
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace WordsRandom
{
class Program
{
static void Main(string[] args)
{
do
{
var str = Console.ReadLine();
Console.WriteLine(RandomWords(str));
} while (true);
}
public struct Pair<TX, TY>
{
public TX X;
public TY Y;
}
public struct Pair
{
public static Pair<TX, TY> Create<TX, TY>(TX x, TY y)
{
return new Pair<TX, TY> { X = x, Y = y };
}
}
static Random _rnd = new Random();
static HashSet<char> _splitChars = new HashSet<char> { '\'', '.', ' ', '\r', '\t', '\n' };
static public string RandomWords(string content)
{
var charArray = new Char[content.Length + 2];
content.CopyTo(0, charArray, 1, content.Length);
charArray[0] = ' ';
charArray[charArray.Length - 1] = ' ';
//标记所有空格
var spaceMarks = charArray
.Select((c, i) => Pair.Create(c, i))
.Where(p => _splitChars.Contains(p.X))
.Select(p => p.Y);
var segs = spaceMarks
.Zip(spaceMarks.Skip(1), (x, y) => Pair.Create(x, y)) //对空格进行两两配对
.Select(p => Pair.Create(p.X + 2, p.Y - p.X - 3)) //计算混淆的起止坐标
.Where(p => p.Y > 1) //没有内容可混淆的过滤掉
.Select(p => new ArraySegment<Char>(charArray, p.X, p.Y));
foreach (var seg in segs)
{
RandomArea(seg);
}
return new string(charArray, 1, charArray.Length - 2);
}
static public void RandomArea(ArraySegment<char> segment)
{
// var chars = new char[segment.Count];
for (int i = 0; i < segment.Count; i++)
{
char tempChar;
var remains = segment.Count - i;//随着循环进行,可以取出的范围减少
var last = remains + segment.Offset - 1;
//随机取出一个 和剩余没有抽取的最后元素交换。最后的元素们就是结果
var chosen = _rnd.Next(0, remains) + segment.Offset;
tempChar = segment.Array[chosen];
segment.Array[chosen] = segment.Array[last];
segment.Array[last] = tempChar;
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment