Jackett/src/Jackett.Common/Utils/StringUtil.cs

182 lines
7.0 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Text.RegularExpressions;
using AngleSharp.Dom;
using AngleSharp.Html;
using Jackett.Common.Helpers;
namespace Jackett.Common.Utils
{
public static class StringUtil
{
public static string StripNonAlphaNumeric(this string str, string replacement = "") =>
StripRegex(str, "[^a-zA-Z0-9 -]", replacement);
public static string StripRegex(string str, string regex, string replacement = "")
{
var rgx = new Regex(regex);
str = rgx.Replace(str, replacement);
return str;
}
// replaces culture specific characters with the corresponding base characters (e.g. è becomes e).
public static string RemoveDiacritics(string s)
{
var normalizedString = s.Normalize(NormalizationForm.FormD);
var stringBuilder = new StringBuilder();
for (var i = 0; i < normalizedString.Length; i++)
{
var c = normalizedString[i];
if (CharUnicodeInfo.GetUnicodeCategory(c) != UnicodeCategory.NonSpacingMark)
stringBuilder.Append(c);
}
return stringBuilder.ToString();
}
public static string FromBase64(string str) =>
Encoding.UTF8.GetString(Convert.FromBase64String(str));
/// <summary>
/// Convert an array of bytes to a string of hex digits
/// </summary>
/// <param name="bytes">array of bytes</param>
/// <returns>String of hex digits</returns>
public static string HexStringFromBytes(byte[] bytes) =>
string.Join("", bytes.Select(b => b.ToString("X2")));
/// <summary>
/// Compute hash for string encoded as UTF8
/// </summary>
/// <param name="s">String to be hashed</param>
/// <returns>40-character hex string</returns>
public static string HashSHA1(string s)
{
var sha1 = SHA1.Create();
var bytes = Encoding.UTF8.GetBytes(s);
var hashBytes = sha1.ComputeHash(bytes);
return HexStringFromBytes(hashBytes);
}
public static string Hash(string s)
{
// Use input string to calculate MD5 hash
var md5 = System.Security.Cryptography.MD5.Create();
var inputBytes = System.Text.Encoding.ASCII.GetBytes(s);
var hashBytes = md5.ComputeHash(inputBytes);
return HexStringFromBytes(hashBytes);
}
// Is never used
// remove in favor of Exception.ToString() ?
public static string GetExceptionDetails(this Exception exception)
{
var properties = exception.GetType()
.GetProperties();
var fields = properties
.Select(property => new
{
Name = property.Name,
Value = property.GetValue(exception, null)
})
.Select(x => string.Format(
"{0} = {1}",
x.Name,
x.Value != null ? x.Value.ToString() : string.Empty
));
return string.Join("\n", fields);
}
private static char[] MakeValidFileName_invalids;
/// <summary>Replaces characters in <c>text</c> that are not allowed in
/// file names with the specified replacement character.</summary>
/// <param name="text">Text to make into a valid filename. The same string is returned if it is valid already.</param>
/// <param name="replacement">Replacement character, or null to simply remove bad characters.</param>
/// <param name="fancy">Whether to replace quotes and slashes with the non-ASCII characters ” and .</param>
/// <returns>A string that can be used as a filename. If the output string would otherwise be empty, returns "_".</returns>
public static string MakeValidFileName(string text, char? replacement = '_', bool fancy = true)
{
var sb = new StringBuilder(text.Length);
var invalids = MakeValidFileName_invalids ?? (MakeValidFileName_invalids = Path.GetInvalidFileNameChars());
var changed = false;
for (var i = 0; i < text.Length; i++)
{
var c = text[i];
if (invalids.Contains(c))
{
changed = true;
var repl = replacement ?? '\0';
if (fancy)
{
if (c == '"')
repl = '”'; // U+201D right double quotation mark
else if (c == '\'')
repl = ''; // U+2019 right single quotation mark
else if (c == '/')
repl = ''; // U+2044 fraction slash
}
if (repl != '\0')
sb.Append(repl);
}
else
sb.Append(c);
}
if (sb.Length == 0)
return "_";
return changed ? sb.ToString() : text;
}
public static string GetQueryString(this NameValueCollection collection, Encoding encoding = null) =>
string.Join("&", collection.AllKeys.Select(a =>
$"{a}={WebUtilityHelpers.UrlEncode(collection[a], encoding ?? Encoding.UTF8)}"));
public static string GetQueryString(this ICollection<KeyValuePair<string, string>> collection, Encoding encoding = null) =>
string.Join("&", collection.Select(a =>
$"{a.Key}={WebUtilityHelpers.UrlEncode(a.Value, encoding ?? Encoding.UTF8)}"));
public static void Add(this ICollection<KeyValuePair<string, string>> collection, string key, string value) => collection.Add(new KeyValuePair<string, string>(key, value));
public static string ToHtmlPretty(this IElement element)
{
if (element == null)
return "<NULL>";
var sb = new StringBuilder();
var sw = new StringWriter(sb);
var formatter = new PrettyMarkupFormatter();
element.ToHtml(sw, formatter);
return sb.ToString();
}
public static string GenerateRandom(int length)
{
var chars = "abcdefghijklmnopqrstuvwxyz0123456789";
var randBytes = new byte[length];
using (var rngCsp = new RNGCryptoServiceProvider())
{
rngCsp.GetBytes(randBytes);
var key = "";
foreach (var b in randBytes)
{
key += chars[b % chars.Length];
}
return key;
}
}
}
}